/**
* AutoLayout.js is licensed under the MIT license. If a copy of the
* MIT-license was not distributed with this file, You can obtain one at:
* http://opensource.org/licenses/mit-license.html.
*
* @author: Hein Rutjes (IjzerenHein)
* @license MIT
* @copyright Gloey Apps, 2017
*
* @library autolayout.js
* @version 0.7.0
*/
/**
* Parts Copyright (C) 2011-2012, Alex Russell (slightlyoff@chromium.org)
* Parts Copyright (C) Copyright (C) 1998-2000 Greg J. Badros
*
* Use of this source code is governed by the LGPL, which can be found in the
* COPYING.LGPL file.
*/
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.AutoLayout = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
    'use strict';
    
    var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
    
    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
    
    var c = require('cassowary/bin/c');
    'use strict';
    
    /**
     * Layout attributes.
     * @enum {String}
     */
    var Attribute = {
      CONST: 'const',
      NOTANATTRIBUTE: 'const',
      VARIABLE: 'var',
      LEFT: 'left',
      RIGHT: 'right',
      TOP: 'top',
      BOTTOM: 'bottom',
      WIDTH: 'width',
      HEIGHT: 'height',
      CENTERX: 'centerX',
      CENTERY: 'centerY',
      /*LEADING: 'leading',
      TRAILING: 'trailing'*/
      /** Used by the extended VFL syntax. */
      ZINDEX: 'zIndex'
    };
    
    /**
     * Relation types.
     * @enum {String}
     */
    var Relation = {
      /** Less than or equal */
      LEQ: 'leq',
      /** Equal */
      EQU: 'equ',
      /** Greater than or equal */
      GEQ: 'geq'
    };
    
    /**
     * Layout priorities.
     * @enum {String}
     */
    var Priority = {
      REQUIRED: 1000,
      DEFAULTHIGH: 750,
      DEFAULTLOW: 250
      //FITTINGSIZELEVEL: 50,
    };
    
    var parser = function () {
      /*
       * Generated by PEG.js 0.8.0.
       *
       * http://pegjs.majda.cz/
       */
    
      function peg$subclass(child, parent) {
        function ctor() {
          this.constructor = child;
        }
        ctor.prototype = parent.prototype;
        child.prototype = new ctor();
      }
    
      function SyntaxError(message, expected, found, offset, line, column) {
        this.message = message;
        this.expected = expected;
        this.found = found;
        this.offset = offset;
        this.line = line;
        this.column = column;
    
        this.name = "SyntaxError";
      }
    
      peg$subclass(SyntaxError, Error);
    
      function parse(input) {
        var options = arguments.length > 1 ? arguments[1] : {},
            peg$FAILED = {},
            peg$startRuleFunctions = { visualFormatString: peg$parsevisualFormatString },
            peg$startRuleFunction = peg$parsevisualFormatString,
            peg$c0 = peg$FAILED,
            peg$c1 = null,
            peg$c2 = ":",
            peg$c3 = { type: "literal", value: ":", description: "\":\"" },
            peg$c4 = [],
            peg$c5 = function peg$c5(o, superto, view, views, tosuper) {
          return {
            orientation: o ? o[0] : 'horizontal',
            cascade: (superto || []).concat([view], [].concat.apply([], views), tosuper || [])
          };
        },
            peg$c6 = "H",
            peg$c7 = { type: "literal", value: "H", description: "\"H\"" },
            peg$c8 = "V",
            peg$c9 = { type: "literal", value: "V", description: "\"V\"" },
            peg$c10 = function peg$c10(orient) {
          return orient == 'H' ? 'horizontal' : 'vertical';
        },
            peg$c11 = "|",
            peg$c12 = { type: "literal", value: "|", description: "\"|\"" },
            peg$c13 = function peg$c13() {
          return { view: null };
        },
            peg$c14 = "[",
            peg$c15 = { type: "literal", value: "[", description: "\"[\"" },
            peg$c16 = "]",
            peg$c17 = { type: "literal", value: "]", description: "\"]\"" },
            peg$c18 = function peg$c18(view, predicates) {
          return extend(view, predicates ? { constraints: predicates } : {});
        },
            peg$c19 = "-",
            peg$c20 = { type: "literal", value: "-", description: "\"-\"" },
            peg$c21 = function peg$c21(predicateList) {
          return predicateList;
        },
            peg$c22 = function peg$c22() {
          return [{ relation: 'equ', constant: 'default', $parserOffset: offset() }];
        },
            peg$c23 = "",
            peg$c24 = function peg$c24() {
          return [{ relation: 'equ', constant: 0, $parserOffset: offset() }];
        },
            peg$c25 = function peg$c25(n) {
          return [{ relation: 'equ', constant: n, $parserOffset: offset() }];
        },
            peg$c26 = "(",
            peg$c27 = { type: "literal", value: "(", description: "\"(\"" },
            peg$c28 = ",",
            peg$c29 = { type: "literal", value: ",", description: "\",\"" },
            peg$c30 = ")",
            peg$c31 = { type: "literal", value: ")", description: "\")\"" },
            peg$c32 = function peg$c32(p, ps) {
          return [p].concat(ps.map(function (p) {
            return p[1];
          }));
        },
            peg$c33 = "@",
            peg$c34 = { type: "literal", value: "@", description: "\"@\"" },
            peg$c35 = function peg$c35(r, o, p) {
          return extend({ relation: 'equ' }, r || {}, o, p ? p[1] : {});
        },
            peg$c36 = "==",
            peg$c37 = { type: "literal", value: "==", description: "\"==\"" },
            peg$c38 = function peg$c38() {
          return { relation: 'equ', $parserOffset: offset() };
        },
            peg$c39 = "<=",
            peg$c40 = { type: "literal", value: "<=", description: "\"<=\"" },
            peg$c41 = function peg$c41() {
          return { relation: 'leq', $parserOffset: offset() };
        },
            peg$c42 = ">=",
            peg$c43 = { type: "literal", value: ">=", description: "\">=\"" },
            peg$c44 = function peg$c44() {
          return { relation: 'geq', $parserOffset: offset() };
        },
            peg$c45 = /^[0-9]/,
            peg$c46 = { type: "class", value: "[0-9]", description: "[0-9]" },
            peg$c47 = function peg$c47(digits) {
          return { priority: parseInt(digits.join(""), 10) };
        },
            peg$c48 = function peg$c48(n) {
          return { constant: n };
        },
            peg$c49 = /^[a-zA-Z_]/,
            peg$c50 = { type: "class", value: "[a-zA-Z_]", description: "[a-zA-Z_]" },
            peg$c51 = /^[a-zA-Z0-9_]/,
            peg$c52 = { type: "class", value: "[a-zA-Z0-9_]", description: "[a-zA-Z0-9_]" },
            peg$c53 = function peg$c53(f, v) {
          return { view: f + v };
        },
            peg$c54 = ".",
            peg$c55 = { type: "literal", value: ".", description: "\".\"" },
            peg$c56 = function peg$c56(digits, decimals) {
          return parseFloat(digits.concat(".").concat(decimals).join(""), 10);
        },
            peg$c57 = function peg$c57(digits) {
          return parseInt(digits.join(""), 10);
        },
            peg$currPos = 0,
            peg$reportedPos = 0,
            peg$cachedPos = 0,
            peg$cachedPosDetails = { line: 1, column: 1, seenCR: false },
            peg$maxFailPos = 0,
            peg$maxFailExpected = [],
            peg$silentFails = 0,
            peg$result;
    
        if ("startRule" in options) {
          if (!(options.startRule in peg$startRuleFunctions)) {
            throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
          }
    
          peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
        }
    
        function text() {
          return input.substring(peg$reportedPos, peg$currPos);
        }
    
        function offset() {
          return peg$reportedPos;
        }
    
        function line() {
          return peg$computePosDetails(peg$reportedPos).line;
        }
    
        function column() {
          return peg$computePosDetails(peg$reportedPos).column;
        }
    
        function expected(description) {
          throw peg$buildException(null, [{ type: "other", description: description }], peg$reportedPos);
        }
    
        function error(message) {
          throw peg$buildException(message, null, peg$reportedPos);
        }
    
        function peg$computePosDetails(pos) {
          function advance(details, startPos, endPos) {
            var p, ch;
    
            for (p = startPos; p < endPos; p++) {
              ch = input.charAt(p);
              if (ch === "\n") {
                if (!details.seenCR) {
                  details.line++;
                }
                details.column = 1;
                details.seenCR = false;
              } else if (ch === "\r" || ch === '\u2028' || ch === '\u2029') {
                details.line++;
                details.column = 1;
                details.seenCR = true;
              } else {
                details.column++;
                details.seenCR = false;
              }
            }
          }
    
          if (peg$cachedPos !== pos) {
            if (peg$cachedPos > pos) {
              peg$cachedPos = 0;
              peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
            }
            advance(peg$cachedPosDetails, peg$cachedPos, pos);
            peg$cachedPos = pos;
          }
    
          return peg$cachedPosDetails;
        }
    
        function peg$fail(expected) {
          if (peg$currPos < peg$maxFailPos) {
            return;
          }
    
          if (peg$currPos > peg$maxFailPos) {
            peg$maxFailPos = peg$currPos;
            peg$maxFailExpected = [];
          }
    
          peg$maxFailExpected.push(expected);
        }
    
        function peg$buildException(message, expected, pos) {
          function cleanupExpected(expected) {
            var i = 1;
    
            expected.sort(function (a, b) {
              if (a.description < b.description) {
                return -1;
              } else if (a.description > b.description) {
                return 1;
              } else {
                return 0;
              }
            });
    
            while (i < expected.length) {
              if (expected[i - 1] === expected[i]) {
                expected.splice(i, 1);
              } else {
                i++;
              }
            }
          }
    
          function buildMessage(expected, found) {
            function stringEscape(s) {
              function hex(ch) {
                return ch.charCodeAt(0).toString(16).toUpperCase();
              }
    
              return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\x08/g, '\\b').replace(/\t/g, '\\t').replace(/\n/g, '\\n').replace(/\f/g, '\\f').replace(/\r/g, '\\r').replace(/[\x00-\x07\x0B\x0E\x0F]/g, function (ch) {
                return '\\x0' + hex(ch);
              }).replace(/[\x10-\x1F\x80-\xFF]/g, function (ch) {
                return '\\x' + hex(ch);
              }).replace(/[\u0180-\u0FFF]/g, function (ch) {
                return '\\u0' + hex(ch);
              }).replace(/[\u1080-\uFFFF]/g, function (ch) {
                return '\\u' + hex(ch);
              });
            }
    
            var expectedDescs = new Array(expected.length),
                expectedDesc,
                foundDesc,
                i;
    
            for (i = 0; i < expected.length; i++) {
              expectedDescs[i] = expected[i].description;
            }
    
            expectedDesc = expected.length > 1 ? expectedDescs.slice(0, -1).join(", ") + " or " + expectedDescs[expected.length - 1] : expectedDescs[0];
    
            foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
    
            return "Expected " + expectedDesc + " but " + foundDesc + " found.";
          }
    
          var posDetails = peg$computePosDetails(pos),
              found = pos < input.length ? input.charAt(pos) : null;
    
          if (expected !== null) {
            cleanupExpected(expected);
          }
    
          return new SyntaxError(message !== null ? message : buildMessage(expected, found), expected, found, pos, posDetails.line, posDetails.column);
        }
    
        function peg$parsevisualFormatString() {
          var s0, s1, s2, s3, s4, s5, s6, s7;
    
          s0 = peg$currPos;
          s1 = peg$currPos;
          s2 = peg$parseorientation();
          if (s2 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 58) {
              s3 = peg$c2;
              peg$currPos++;
            } else {
              s3 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c3);
              }
            }
            if (s3 !== peg$FAILED) {
              s2 = [s2, s3];
              s1 = s2;
            } else {
              peg$currPos = s1;
              s1 = peg$c0;
            }
          } else {
            peg$currPos = s1;
            s1 = peg$c0;
          }
          if (s1 === peg$FAILED) {
            s1 = peg$c1;
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$currPos;
            s3 = peg$parsesuperview();
            if (s3 !== peg$FAILED) {
              s4 = peg$parseconnection();
              if (s4 !== peg$FAILED) {
                s3 = [s3, s4];
                s2 = s3;
              } else {
                peg$currPos = s2;
                s2 = peg$c0;
              }
            } else {
              peg$currPos = s2;
              s2 = peg$c0;
            }
            if (s2 === peg$FAILED) {
              s2 = peg$c1;
            }
            if (s2 !== peg$FAILED) {
              s3 = peg$parseview();
              if (s3 !== peg$FAILED) {
                s4 = [];
                s5 = peg$currPos;
                s6 = peg$parseconnection();
                if (s6 !== peg$FAILED) {
                  s7 = peg$parseview();
                  if (s7 !== peg$FAILED) {
                    s6 = [s6, s7];
                    s5 = s6;
                  } else {
                    peg$currPos = s5;
                    s5 = peg$c0;
                  }
                } else {
                  peg$currPos = s5;
                  s5 = peg$c0;
                }
                while (s5 !== peg$FAILED) {
                  s4.push(s5);
                  s5 = peg$currPos;
                  s6 = peg$parseconnection();
                  if (s6 !== peg$FAILED) {
                    s7 = peg$parseview();
                    if (s7 !== peg$FAILED) {
                      s6 = [s6, s7];
                      s5 = s6;
                    } else {
                      peg$currPos = s5;
                      s5 = peg$c0;
                    }
                  } else {
                    peg$currPos = s5;
                    s5 = peg$c0;
                  }
                }
                if (s4 !== peg$FAILED) {
                  s5 = peg$currPos;
                  s6 = peg$parseconnection();
                  if (s6 !== peg$FAILED) {
                    s7 = peg$parsesuperview();
                    if (s7 !== peg$FAILED) {
                      s6 = [s6, s7];
                      s5 = s6;
                    } else {
                      peg$currPos = s5;
                      s5 = peg$c0;
                    }
                  } else {
                    peg$currPos = s5;
                    s5 = peg$c0;
                  }
                  if (s5 === peg$FAILED) {
                    s5 = peg$c1;
                  }
                  if (s5 !== peg$FAILED) {
                    peg$reportedPos = s0;
                    s1 = peg$c5(s1, s2, s3, s4, s5);
                    s0 = s1;
                  } else {
                    peg$currPos = s0;
                    s0 = peg$c0;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parseorientation() {
          var s0, s1;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 72) {
            s1 = peg$c6;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c7);
            }
          }
          if (s1 === peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 86) {
              s1 = peg$c8;
              peg$currPos++;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c9);
              }
            }
          }
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c10(s1);
          }
          s0 = s1;
    
          return s0;
        }
    
        function peg$parsesuperview() {
          var s0, s1;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 124) {
            s1 = peg$c11;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c12);
            }
          }
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c13();
          }
          s0 = s1;
    
          return s0;
        }
    
        function peg$parseview() {
          var s0, s1, s2, s3, s4;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 91) {
            s1 = peg$c14;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c15);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parseviewName();
            if (s2 !== peg$FAILED) {
              s3 = peg$parsepredicateListWithParens();
              if (s3 === peg$FAILED) {
                s3 = peg$c1;
              }
              if (s3 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 93) {
                  s4 = peg$c16;
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c17);
                  }
                }
                if (s4 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c18(s2, s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parseconnection() {
          var s0, s1, s2, s3;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 45) {
            s1 = peg$c19;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c20);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parsepredicateList();
            if (s2 !== peg$FAILED) {
              if (input.charCodeAt(peg$currPos) === 45) {
                s3 = peg$c19;
                peg$currPos++;
              } else {
                s3 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c20);
                }
              }
              if (s3 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c21(s2);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            if (input.charCodeAt(peg$currPos) === 45) {
              s1 = peg$c19;
              peg$currPos++;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c20);
              }
            }
            if (s1 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c22();
            }
            s0 = s1;
            if (s0 === peg$FAILED) {
              s0 = peg$currPos;
              s1 = peg$c23;
              if (s1 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c24();
              }
              s0 = s1;
            }
          }
    
          return s0;
        }
    
        function peg$parsepredicateList() {
          var s0;
    
          s0 = peg$parsesimplePredicate();
          if (s0 === peg$FAILED) {
            s0 = peg$parsepredicateListWithParens();
          }
    
          return s0;
        }
    
        function peg$parsesimplePredicate() {
          var s0, s1;
    
          s0 = peg$currPos;
          s1 = peg$parsenumber();
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c25(s1);
          }
          s0 = s1;
    
          return s0;
        }
    
        function peg$parsepredicateListWithParens() {
          var s0, s1, s2, s3, s4, s5, s6;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 40) {
            s1 = peg$c26;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c27);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parsepredicate();
            if (s2 !== peg$FAILED) {
              s3 = [];
              s4 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 44) {
                s5 = peg$c28;
                peg$currPos++;
              } else {
                s5 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c29);
                }
              }
              if (s5 !== peg$FAILED) {
                s6 = peg$parsepredicate();
                if (s6 !== peg$FAILED) {
                  s5 = [s5, s6];
                  s4 = s5;
                } else {
                  peg$currPos = s4;
                  s4 = peg$c0;
                }
              } else {
                peg$currPos = s4;
                s4 = peg$c0;
              }
              while (s4 !== peg$FAILED) {
                s3.push(s4);
                s4 = peg$currPos;
                if (input.charCodeAt(peg$currPos) === 44) {
                  s5 = peg$c28;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c29);
                  }
                }
                if (s5 !== peg$FAILED) {
                  s6 = peg$parsepredicate();
                  if (s6 !== peg$FAILED) {
                    s5 = [s5, s6];
                    s4 = s5;
                  } else {
                    peg$currPos = s4;
                    s4 = peg$c0;
                  }
                } else {
                  peg$currPos = s4;
                  s4 = peg$c0;
                }
              }
              if (s3 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 41) {
                  s4 = peg$c30;
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c31);
                  }
                }
                if (s4 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c32(s2, s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parsepredicate() {
          var s0, s1, s2, s3, s4, s5;
    
          s0 = peg$currPos;
          s1 = peg$parserelation();
          if (s1 === peg$FAILED) {
            s1 = peg$c1;
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parseobjectOfPredicate();
            if (s2 !== peg$FAILED) {
              s3 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 64) {
                s4 = peg$c33;
                peg$currPos++;
              } else {
                s4 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c34);
                }
              }
              if (s4 !== peg$FAILED) {
                s5 = peg$parsepriority();
                if (s5 !== peg$FAILED) {
                  s4 = [s4, s5];
                  s3 = s4;
                } else {
                  peg$currPos = s3;
                  s3 = peg$c0;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$c0;
              }
              if (s3 === peg$FAILED) {
                s3 = peg$c1;
              }
              if (s3 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c35(s1, s2, s3);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parserelation() {
          var s0, s1;
    
          s0 = peg$currPos;
          if (input.substr(peg$currPos, 2) === peg$c36) {
            s1 = peg$c36;
            peg$currPos += 2;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c37);
            }
          }
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c38();
          }
          s0 = s1;
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            if (input.substr(peg$currPos, 2) === peg$c39) {
              s1 = peg$c39;
              peg$currPos += 2;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c40);
              }
            }
            if (s1 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c41();
            }
            s0 = s1;
            if (s0 === peg$FAILED) {
              s0 = peg$currPos;
              if (input.substr(peg$currPos, 2) === peg$c42) {
                s1 = peg$c42;
                peg$currPos += 2;
              } else {
                s1 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c43);
                }
              }
              if (s1 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c44();
              }
              s0 = s1;
            }
          }
    
          return s0;
        }
    
        function peg$parseobjectOfPredicate() {
          var s0;
    
          s0 = peg$parseconstant();
          if (s0 === peg$FAILED) {
            s0 = peg$parseviewName();
          }
    
          return s0;
        }
    
        function peg$parsepriority() {
          var s0, s1, s2;
    
          s0 = peg$currPos;
          s1 = [];
          if (peg$c45.test(input.charAt(peg$currPos))) {
            s2 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s2 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c46);
            }
          }
          if (s2 !== peg$FAILED) {
            while (s2 !== peg$FAILED) {
              s1.push(s2);
              if (peg$c45.test(input.charAt(peg$currPos))) {
                s2 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s2 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c46);
                }
              }
            }
          } else {
            s1 = peg$c0;
          }
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c47(s1);
          }
          s0 = s1;
    
          return s0;
        }
    
        function peg$parseconstant() {
          var s0, s1;
    
          s0 = peg$currPos;
          s1 = peg$parsenumber();
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c48(s1);
          }
          s0 = s1;
    
          return s0;
        }
    
        function peg$parseviewName() {
          var s0, s1, s2, s3, s4;
    
          s0 = peg$currPos;
          s1 = peg$currPos;
          s2 = [];
          if (peg$c49.test(input.charAt(peg$currPos))) {
            s3 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s3 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c50);
            }
          }
          if (s3 !== peg$FAILED) {
            while (s3 !== peg$FAILED) {
              s2.push(s3);
              if (peg$c49.test(input.charAt(peg$currPos))) {
                s3 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s3 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c50);
                }
              }
            }
          } else {
            s2 = peg$c0;
          }
          if (s2 !== peg$FAILED) {
            s2 = input.substring(s1, peg$currPos);
          }
          s1 = s2;
          if (s1 !== peg$FAILED) {
            s2 = peg$currPos;
            s3 = [];
            if (peg$c51.test(input.charAt(peg$currPos))) {
              s4 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s4 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c52);
              }
            }
            while (s4 !== peg$FAILED) {
              s3.push(s4);
              if (peg$c51.test(input.charAt(peg$currPos))) {
                s4 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s4 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c52);
                }
              }
            }
            if (s3 !== peg$FAILED) {
              s3 = input.substring(s2, peg$currPos);
            }
            s2 = s3;
            if (s2 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c53(s1, s2);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parsenumber() {
          var s0, s1, s2, s3, s4;
    
          s0 = peg$currPos;
          s1 = [];
          if (peg$c45.test(input.charAt(peg$currPos))) {
            s2 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s2 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c46);
            }
          }
          if (s2 !== peg$FAILED) {
            while (s2 !== peg$FAILED) {
              s1.push(s2);
              if (peg$c45.test(input.charAt(peg$currPos))) {
                s2 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s2 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c46);
                }
              }
            }
          } else {
            s1 = peg$c0;
          }
          if (s1 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 46) {
              s2 = peg$c54;
              peg$currPos++;
            } else {
              s2 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c55);
              }
            }
            if (s2 !== peg$FAILED) {
              s3 = [];
              if (peg$c45.test(input.charAt(peg$currPos))) {
                s4 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s4 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c46);
                }
              }
              if (s4 !== peg$FAILED) {
                while (s4 !== peg$FAILED) {
                  s3.push(s4);
                  if (peg$c45.test(input.charAt(peg$currPos))) {
                    s4 = input.charAt(peg$currPos);
                    peg$currPos++;
                  } else {
                    s4 = peg$FAILED;
                    if (peg$silentFails === 0) {
                      peg$fail(peg$c46);
                    }
                  }
                }
              } else {
                s3 = peg$c0;
              }
              if (s3 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c56(s1, s3);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            s1 = [];
            if (peg$c45.test(input.charAt(peg$currPos))) {
              s2 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s2 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c46);
              }
            }
            if (s2 !== peg$FAILED) {
              while (s2 !== peg$FAILED) {
                s1.push(s2);
                if (peg$c45.test(input.charAt(peg$currPos))) {
                  s2 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s2 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c46);
                  }
                }
              }
            } else {
              s1 = peg$c0;
            }
            if (s1 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c57(s1);
            }
            s0 = s1;
          }
    
          return s0;
        }
    
        function extend(dst) {
          for (var i = 1; i < arguments.length; i++) {
            for (var k in arguments[i]) {
              dst[k] = arguments[i][k];
            }
          }
          return dst;
        }
    
        peg$result = peg$startRuleFunction();
    
        if (peg$result !== peg$FAILED && peg$currPos === input.length) {
          return peg$result;
        } else {
          if (peg$result !== peg$FAILED && peg$currPos < input.length) {
            peg$fail({ type: "end", description: "end of input" });
          }
    
          throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
        }
      }
    
      return {
        SyntaxError: SyntaxError,
        parse: parse
      };
    }();
    
    var parserExt = function () {
      /*
       * Generated by PEG.js 0.8.0.
       *
       * http://pegjs.majda.cz/
       */
    
      function peg$subclass(child, parent) {
        function ctor() {
          this.constructor = child;
        }
        ctor.prototype = parent.prototype;
        child.prototype = new ctor();
      }
    
      function SyntaxError(message, expected, found, offset, line, column) {
        this.message = message;
        this.expected = expected;
        this.found = found;
        this.offset = offset;
        this.line = line;
        this.column = column;
    
        this.name = "SyntaxError";
      }
    
      peg$subclass(SyntaxError, Error);
    
      function parse(input) {
        var options = arguments.length > 1 ? arguments[1] : {},
            peg$FAILED = {},
            peg$startRuleFunctions = { visualFormatStringExt: peg$parsevisualFormatStringExt },
            peg$startRuleFunction = peg$parsevisualFormatStringExt,
            peg$c0 = peg$FAILED,
            peg$c1 = "C:",
            peg$c2 = { type: "literal", value: "C:", description: "\"C:\"" },
            peg$c3 = [],
            peg$c4 = null,
            peg$c5 = function peg$c5(view, attribute, attributes, comments) {
          return {
            type: 'attribute',
            view: view.view,
            attributes: [attribute].concat(attributes)
          };
        },
            peg$c6 = function peg$c6(attr, predicates) {
          return { attr: attr, predicates: predicates };
        },
            peg$c7 = ":",
            peg$c8 = { type: "literal", value: ":", description: "\":\"" },
            peg$c9 = function peg$c9(o, superto, view, views, tosuper, comments) {
          return {
            type: 'vfl',
            orientation: o ? o[0] : 'horizontal',
            cascade: (superto || []).concat(view, [].concat.apply([], views), tosuper || [])
          };
        },
            peg$c10 = "HV",
            peg$c11 = { type: "literal", value: "HV", description: "\"HV\"" },
            peg$c12 = function peg$c12() {
          return 'horzvert';
        },
            peg$c13 = "H",
            peg$c14 = { type: "literal", value: "H", description: "\"H\"" },
            peg$c15 = function peg$c15() {
          return 'horizontal';
        },
            peg$c16 = "V",
            peg$c17 = { type: "literal", value: "V", description: "\"V\"" },
            peg$c18 = function peg$c18() {
          return 'vertical';
        },
            peg$c19 = "Z",
            peg$c20 = { type: "literal", value: "Z", description: "\"Z\"" },
            peg$c21 = function peg$c21() {
          return 'zIndex';
        },
            peg$c22 = " ",
            peg$c23 = { type: "literal", value: " ", description: "\" \"" },
            peg$c24 = "//",
            peg$c25 = { type: "literal", value: "//", description: "\"//\"" },
            peg$c26 = { type: "any", description: "any character" },
            peg$c27 = "|",
            peg$c28 = { type: "literal", value: "|", description: "\"|\"" },
            peg$c29 = function peg$c29() {
          return { view: null };
        },
            peg$c30 = "[",
            peg$c31 = { type: "literal", value: "[", description: "\"[\"" },
            peg$c32 = ",",
            peg$c33 = { type: "literal", value: ",", description: "\",\"" },
            peg$c34 = "]",
            peg$c35 = { type: "literal", value: "]", description: "\"]\"" },
            peg$c36 = function peg$c36(view, views) {
          return views.length ? [view].concat([].concat.apply([], views)) : view;
        },
            peg$c37 = function peg$c37(view, predicates, cascadedViews) {
          return extend(extend(view, predicates ? { constraints: predicates } : {}), cascadedViews ? {
            cascade: cascadedViews
          } : {});
        },
            peg$c38 = function peg$c38(views, connection) {
          return [].concat([].concat.apply([], views), [connection]);
        },
            peg$c39 = "->",
            peg$c40 = { type: "literal", value: "->", description: "\"->\"" },
            peg$c41 = function peg$c41() {
          return [{ relation: 'none' }];
        },
            peg$c42 = "-",
            peg$c43 = { type: "literal", value: "-", description: "\"-\"" },
            peg$c44 = function peg$c44(predicateList) {
          return predicateList;
        },
            peg$c45 = function peg$c45() {
          return [{ relation: 'equ', constant: 'default' }];
        },
            peg$c46 = "~",
            peg$c47 = { type: "literal", value: "~", description: "\"~\"" },
            peg$c48 = function peg$c48() {
          return [{ relation: 'equ', equalSpacing: true }];
        },
            peg$c49 = "",
            peg$c50 = function peg$c50() {
          return [{ relation: 'equ', constant: 0 }];
        },
            peg$c51 = function peg$c51(p) {
          return [{ relation: 'equ', multiplier: p.multiplier }];
        },
            peg$c52 = function peg$c52(n) {
          return [{ relation: 'equ', constant: n }];
        },
            peg$c53 = "(",
            peg$c54 = { type: "literal", value: "(", description: "\"(\"" },
            peg$c55 = ")",
            peg$c56 = { type: "literal", value: ")", description: "\")\"" },
            peg$c57 = function peg$c57(p, ps) {
          return [p].concat(ps.map(function (p) {
            return p[1];
          }));
        },
            peg$c58 = "@",
            peg$c59 = { type: "literal", value: "@", description: "\"@\"" },
            peg$c60 = function peg$c60(r, o, p) {
          return extend({ relation: 'equ' }, r || {}, o, p ? p[1] : {});
        },
            peg$c61 = function peg$c61(r, o, p) {
          return extend({ relation: 'equ', equalSpacing: true }, r || {}, o, p ? p[1] : {});
        },
            peg$c62 = "==",
            peg$c63 = { type: "literal", value: "==", description: "\"==\"" },
            peg$c64 = function peg$c64() {
          return { relation: 'equ' };
        },
            peg$c65 = "<=",
            peg$c66 = { type: "literal", value: "<=", description: "\"<=\"" },
            peg$c67 = function peg$c67() {
          return { relation: 'leq' };
        },
            peg$c68 = ">=",
            peg$c69 = { type: "literal", value: ">=", description: "\">=\"" },
            peg$c70 = function peg$c70() {
          return { relation: 'geq' };
        },
            peg$c71 = /^[0-9]/,
            peg$c72 = { type: "class", value: "[0-9]", description: "[0-9]" },
            peg$c73 = function peg$c73(digits) {
          return { priority: parseInt(digits.join(""), 10) };
        },
            peg$c74 = function peg$c74(n) {
          return { constant: n };
        },
            peg$c75 = function peg$c75(n) {
          return { constant: -n };
        },
            peg$c76 = "+",
            peg$c77 = { type: "literal", value: "+", description: "\"+\"" },
            peg$c78 = "%",
            peg$c79 = { type: "literal", value: "%", description: "\"%\"" },
            peg$c80 = function peg$c80(n) {
          return { view: null, multiplier: n / 100 };
        },
            peg$c81 = function peg$c81(n) {
          return { view: null, multiplier: n / -100 };
        },
            peg$c82 = function peg$c82(vn, a, m, c) {
          return { view: vn.view, attribute: a ? a : undefined, multiplier: m ? m : 1, constant: c ? c : undefined };
        },
            peg$c83 = ".left",
            peg$c84 = { type: "literal", value: ".left", description: "\".left\"" },
            peg$c85 = function peg$c85() {
          return 'left';
        },
            peg$c86 = ".right",
            peg$c87 = { type: "literal", value: ".right", description: "\".right\"" },
            peg$c88 = function peg$c88() {
          return 'right';
        },
            peg$c89 = ".top",
            peg$c90 = { type: "literal", value: ".top", description: "\".top\"" },
            peg$c91 = function peg$c91() {
          return 'top';
        },
            peg$c92 = ".bottom",
            peg$c93 = { type: "literal", value: ".bottom", description: "\".bottom\"" },
            peg$c94 = function peg$c94() {
          return 'bottom';
        },
            peg$c95 = ".width",
            peg$c96 = { type: "literal", value: ".width", description: "\".width\"" },
            peg$c97 = function peg$c97() {
          return 'width';
        },
            peg$c98 = ".height",
            peg$c99 = { type: "literal", value: ".height", description: "\".height\"" },
            peg$c100 = function peg$c100() {
          return 'height';
        },
            peg$c101 = ".centerX",
            peg$c102 = { type: "literal", value: ".centerX", description: "\".centerX\"" },
            peg$c103 = function peg$c103() {
          return 'centerX';
        },
            peg$c104 = ".centerY",
            peg$c105 = { type: "literal", value: ".centerY", description: "\".centerY\"" },
            peg$c106 = function peg$c106() {
          return 'centerY';
        },
            peg$c107 = "/",
            peg$c108 = { type: "literal", value: "/", description: "\"/\"" },
            peg$c109 = function peg$c109(n) {
          return 1 / n;
        },
            peg$c110 = "/+",
            peg$c111 = { type: "literal", value: "/+", description: "\"/+\"" },
            peg$c112 = "/-",
            peg$c113 = { type: "literal", value: "/-", description: "\"/-\"" },
            peg$c114 = function peg$c114(n) {
          return -1 / n;
        },
            peg$c115 = "*",
            peg$c116 = { type: "literal", value: "*", description: "\"*\"" },
            peg$c117 = function peg$c117(n) {
          return n;
        },
            peg$c118 = "*+",
            peg$c119 = { type: "literal", value: "*+", description: "\"*+\"" },
            peg$c120 = "*-",
            peg$c121 = { type: "literal", value: "*-", description: "\"*-\"" },
            peg$c122 = function peg$c122(n) {
          return -n;
        },
            peg$c123 = /^[a-zA-Z_]/,
            peg$c124 = { type: "class", value: "[a-zA-Z_]", description: "[a-zA-Z_]" },
            peg$c125 = /^[a-zA-Z0-9_]/,
            peg$c126 = { type: "class", value: "[a-zA-Z0-9_]", description: "[a-zA-Z0-9_]" },
            peg$c127 = function peg$c127(f, v, r) {
          return { view: f + v, range: r, $parserOffset: offset() };
        },
            peg$c128 = function peg$c128(f, v) {
          return { view: f + v, $parserOffset: offset() };
        },
            peg$c129 = "..",
            peg$c130 = { type: "literal", value: "..", description: "\"..\"" },
            peg$c131 = function peg$c131(d) {
          return parseInt(d);
        },
            peg$c132 = ".",
            peg$c133 = { type: "literal", value: ".", description: "\".\"" },
            peg$c134 = function peg$c134(digits, decimals) {
          return parseFloat(digits.concat(".").concat(decimals).join(""), 10);
        },
            peg$c135 = function peg$c135(digits) {
          return parseInt(digits.join(""), 10);
        },
            peg$currPos = 0,
            peg$reportedPos = 0,
            peg$cachedPos = 0,
            peg$cachedPosDetails = { line: 1, column: 1, seenCR: false },
            peg$maxFailPos = 0,
            peg$maxFailExpected = [],
            peg$silentFails = 0,
            peg$result;
    
        if ("startRule" in options) {
          if (!(options.startRule in peg$startRuleFunctions)) {
            throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
          }
    
          peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
        }
    
        function text() {
          return input.substring(peg$reportedPos, peg$currPos);
        }
    
        function offset() {
          return peg$reportedPos;
        }
    
        function line() {
          return peg$computePosDetails(peg$reportedPos).line;
        }
    
        function column() {
          return peg$computePosDetails(peg$reportedPos).column;
        }
    
        function expected(description) {
          throw peg$buildException(null, [{ type: "other", description: description }], peg$reportedPos);
        }
    
        function error(message) {
          throw peg$buildException(message, null, peg$reportedPos);
        }
    
        function peg$computePosDetails(pos) {
          function advance(details, startPos, endPos) {
            var p, ch;
    
            for (p = startPos; p < endPos; p++) {
              ch = input.charAt(p);
              if (ch === "\n") {
                if (!details.seenCR) {
                  details.line++;
                }
                details.column = 1;
                details.seenCR = false;
              } else if (ch === "\r" || ch === '\u2028' || ch === '\u2029') {
                details.line++;
                details.column = 1;
                details.seenCR = true;
              } else {
                details.column++;
                details.seenCR = false;
              }
            }
          }
    
          if (peg$cachedPos !== pos) {
            if (peg$cachedPos > pos) {
              peg$cachedPos = 0;
              peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
            }
            advance(peg$cachedPosDetails, peg$cachedPos, pos);
            peg$cachedPos = pos;
          }
    
          return peg$cachedPosDetails;
        }
    
        function peg$fail(expected) {
          if (peg$currPos < peg$maxFailPos) {
            return;
          }
    
          if (peg$currPos > peg$maxFailPos) {
            peg$maxFailPos = peg$currPos;
            peg$maxFailExpected = [];
          }
    
          peg$maxFailExpected.push(expected);
        }
    
        function peg$buildException(message, expected, pos) {
          function cleanupExpected(expected) {
            var i = 1;
    
            expected.sort(function (a, b) {
              if (a.description < b.description) {
                return -1;
              } else if (a.description > b.description) {
                return 1;
              } else {
                return 0;
              }
            });
    
            while (i < expected.length) {
              if (expected[i - 1] === expected[i]) {
                expected.splice(i, 1);
              } else {
                i++;
              }
            }
          }
    
          function buildMessage(expected, found) {
            function stringEscape(s) {
              function hex(ch) {
                return ch.charCodeAt(0).toString(16).toUpperCase();
              }
    
              return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\x08/g, '\\b').replace(/\t/g, '\\t').replace(/\n/g, '\\n').replace(/\f/g, '\\f').replace(/\r/g, '\\r').replace(/[\x00-\x07\x0B\x0E\x0F]/g, function (ch) {
                return '\\x0' + hex(ch);
              }).replace(/[\x10-\x1F\x80-\xFF]/g, function (ch) {
                return '\\x' + hex(ch);
              }).replace(/[\u0180-\u0FFF]/g, function (ch) {
                return '\\u0' + hex(ch);
              }).replace(/[\u1080-\uFFFF]/g, function (ch) {
                return '\\u' + hex(ch);
              });
            }
    
            var expectedDescs = new Array(expected.length),
                expectedDesc,
                foundDesc,
                i;
    
            for (i = 0; i < expected.length; i++) {
              expectedDescs[i] = expected[i].description;
            }
    
            expectedDesc = expected.length > 1 ? expectedDescs.slice(0, -1).join(", ") + " or " + expectedDescs[expected.length - 1] : expectedDescs[0];
    
            foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
    
            return "Expected " + expectedDesc + " but " + foundDesc + " found.";
          }
    
          var posDetails = peg$computePosDetails(pos),
              found = pos < input.length ? input.charAt(pos) : null;
    
          if (expected !== null) {
            cleanupExpected(expected);
          }
    
          return new SyntaxError(message !== null ? message : buildMessage(expected, found), expected, found, pos, posDetails.line, posDetails.column);
        }
    
        function peg$parsevisualFormatStringExt() {
          var s0;
    
          s0 = peg$parsevisualFormatString();
          if (s0 === peg$FAILED) {
            s0 = peg$parsevisualFormatStringConstraintExpression();
          }
    
          return s0;
        }
    
        function peg$parsevisualFormatStringConstraintExpression() {
          var s0, s1, s2, s3, s4, s5;
    
          s0 = peg$currPos;
          if (input.substr(peg$currPos, 2) === peg$c1) {
            s1 = peg$c1;
            peg$currPos += 2;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c2);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parseviewName();
            if (s2 !== peg$FAILED) {
              s3 = peg$parseattributePredicate();
              if (s3 !== peg$FAILED) {
                s4 = [];
                s5 = peg$parseattributePredicate();
                while (s5 !== peg$FAILED) {
                  s4.push(s5);
                  s5 = peg$parseattributePredicate();
                }
                if (s4 !== peg$FAILED) {
                  s5 = peg$parsecomments();
                  if (s5 === peg$FAILED) {
                    s5 = peg$c4;
                  }
                  if (s5 !== peg$FAILED) {
                    peg$reportedPos = s0;
                    s1 = peg$c5(s2, s3, s4, s5);
                    s0 = s1;
                  } else {
                    peg$currPos = s0;
                    s0 = peg$c0;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parseattributePredicate() {
          var s0, s1, s2;
    
          s0 = peg$currPos;
          s1 = peg$parseattribute();
          if (s1 !== peg$FAILED) {
            s2 = peg$parsepredicateListWithParens();
            if (s2 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c6(s1, s2);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parsevisualFormatString() {
          var s0, s1, s2, s3, s4, s5, s6, s7;
    
          s0 = peg$currPos;
          s1 = peg$currPos;
          s2 = peg$parseorientation();
          if (s2 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 58) {
              s3 = peg$c7;
              peg$currPos++;
            } else {
              s3 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c8);
              }
            }
            if (s3 !== peg$FAILED) {
              s2 = [s2, s3];
              s1 = s2;
            } else {
              peg$currPos = s1;
              s1 = peg$c0;
            }
          } else {
            peg$currPos = s1;
            s1 = peg$c0;
          }
          if (s1 === peg$FAILED) {
            s1 = peg$c4;
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$currPos;
            s3 = peg$parsesuperview();
            if (s3 !== peg$FAILED) {
              s4 = peg$parseconnection();
              if (s4 !== peg$FAILED) {
                s3 = [s3, s4];
                s2 = s3;
              } else {
                peg$currPos = s2;
                s2 = peg$c0;
              }
            } else {
              peg$currPos = s2;
              s2 = peg$c0;
            }
            if (s2 === peg$FAILED) {
              s2 = peg$c4;
            }
            if (s2 !== peg$FAILED) {
              s3 = peg$parseviewGroup();
              if (s3 !== peg$FAILED) {
                s4 = [];
                s5 = peg$currPos;
                s6 = peg$parseconnection();
                if (s6 !== peg$FAILED) {
                  s7 = peg$parseviewGroup();
                  if (s7 !== peg$FAILED) {
                    s6 = [s6, s7];
                    s5 = s6;
                  } else {
                    peg$currPos = s5;
                    s5 = peg$c0;
                  }
                } else {
                  peg$currPos = s5;
                  s5 = peg$c0;
                }
                while (s5 !== peg$FAILED) {
                  s4.push(s5);
                  s5 = peg$currPos;
                  s6 = peg$parseconnection();
                  if (s6 !== peg$FAILED) {
                    s7 = peg$parseviewGroup();
                    if (s7 !== peg$FAILED) {
                      s6 = [s6, s7];
                      s5 = s6;
                    } else {
                      peg$currPos = s5;
                      s5 = peg$c0;
                    }
                  } else {
                    peg$currPos = s5;
                    s5 = peg$c0;
                  }
                }
                if (s4 !== peg$FAILED) {
                  s5 = peg$currPos;
                  s6 = peg$parseconnection();
                  if (s6 !== peg$FAILED) {
                    s7 = peg$parsesuperview();
                    if (s7 !== peg$FAILED) {
                      s6 = [s6, s7];
                      s5 = s6;
                    } else {
                      peg$currPos = s5;
                      s5 = peg$c0;
                    }
                  } else {
                    peg$currPos = s5;
                    s5 = peg$c0;
                  }
                  if (s5 === peg$FAILED) {
                    s5 = peg$c4;
                  }
                  if (s5 !== peg$FAILED) {
                    s6 = peg$parsecomments();
                    if (s6 === peg$FAILED) {
                      s6 = peg$c4;
                    }
                    if (s6 !== peg$FAILED) {
                      peg$reportedPos = s0;
                      s1 = peg$c9(s1, s2, s3, s4, s5, s6);
                      s0 = s1;
                    } else {
                      peg$currPos = s0;
                      s0 = peg$c0;
                    }
                  } else {
                    peg$currPos = s0;
                    s0 = peg$c0;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parseorientation() {
          var s0, s1;
    
          s0 = peg$currPos;
          if (input.substr(peg$currPos, 2) === peg$c10) {
            s1 = peg$c10;
            peg$currPos += 2;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c11);
            }
          }
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c12();
          }
          s0 = s1;
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            if (input.charCodeAt(peg$currPos) === 72) {
              s1 = peg$c13;
              peg$currPos++;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c14);
              }
            }
            if (s1 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c15();
            }
            s0 = s1;
            if (s0 === peg$FAILED) {
              s0 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 86) {
                s1 = peg$c16;
                peg$currPos++;
              } else {
                s1 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c17);
                }
              }
              if (s1 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c18();
              }
              s0 = s1;
              if (s0 === peg$FAILED) {
                s0 = peg$currPos;
                if (input.charCodeAt(peg$currPos) === 90) {
                  s1 = peg$c19;
                  peg$currPos++;
                } else {
                  s1 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c20);
                  }
                }
                if (s1 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c21();
                }
                s0 = s1;
              }
            }
          }
    
          return s0;
        }
    
        function peg$parsecomments() {
          var s0, s1, s2, s3, s4;
    
          s0 = peg$currPos;
          s1 = [];
          if (input.charCodeAt(peg$currPos) === 32) {
            s2 = peg$c22;
            peg$currPos++;
          } else {
            s2 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c23);
            }
          }
          while (s2 !== peg$FAILED) {
            s1.push(s2);
            if (input.charCodeAt(peg$currPos) === 32) {
              s2 = peg$c22;
              peg$currPos++;
            } else {
              s2 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c23);
              }
            }
          }
          if (s1 !== peg$FAILED) {
            if (input.substr(peg$currPos, 2) === peg$c24) {
              s2 = peg$c24;
              peg$currPos += 2;
            } else {
              s2 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c25);
              }
            }
            if (s2 !== peg$FAILED) {
              s3 = [];
              if (input.length > peg$currPos) {
                s4 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s4 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c26);
                }
              }
              while (s4 !== peg$FAILED) {
                s3.push(s4);
                if (input.length > peg$currPos) {
                  s4 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c26);
                  }
                }
              }
              if (s3 !== peg$FAILED) {
                s1 = [s1, s2, s3];
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parsesuperview() {
          var s0, s1;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 124) {
            s1 = peg$c27;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c28);
            }
          }
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c29();
          }
          s0 = s1;
    
          return s0;
        }
    
        function peg$parseviewGroup() {
          var s0, s1, s2, s3, s4, s5, s6;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 91) {
            s1 = peg$c30;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c31);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parseview();
            if (s2 !== peg$FAILED) {
              s3 = [];
              s4 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 44) {
                s5 = peg$c32;
                peg$currPos++;
              } else {
                s5 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c33);
                }
              }
              if (s5 !== peg$FAILED) {
                s6 = peg$parseview();
                if (s6 !== peg$FAILED) {
                  s5 = [s5, s6];
                  s4 = s5;
                } else {
                  peg$currPos = s4;
                  s4 = peg$c0;
                }
              } else {
                peg$currPos = s4;
                s4 = peg$c0;
              }
              while (s4 !== peg$FAILED) {
                s3.push(s4);
                s4 = peg$currPos;
                if (input.charCodeAt(peg$currPos) === 44) {
                  s5 = peg$c32;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c33);
                  }
                }
                if (s5 !== peg$FAILED) {
                  s6 = peg$parseview();
                  if (s6 !== peg$FAILED) {
                    s5 = [s5, s6];
                    s4 = s5;
                  } else {
                    peg$currPos = s4;
                    s4 = peg$c0;
                  }
                } else {
                  peg$currPos = s4;
                  s4 = peg$c0;
                }
              }
              if (s3 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 93) {
                  s4 = peg$c34;
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c35);
                  }
                }
                if (s4 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c36(s2, s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parseview() {
          var s0, s1, s2, s3;
    
          s0 = peg$currPos;
          s1 = peg$parseviewNameRange();
          if (s1 !== peg$FAILED) {
            s2 = peg$parsepredicateListWithParens();
            if (s2 === peg$FAILED) {
              s2 = peg$c4;
            }
            if (s2 !== peg$FAILED) {
              s3 = peg$parsecascadedViews();
              if (s3 === peg$FAILED) {
                s3 = peg$c4;
              }
              if (s3 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c37(s1, s2, s3);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parsecascadedViews() {
          var s0, s1, s2, s3, s4, s5;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 58) {
            s1 = peg$c7;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c8);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = [];
            s3 = peg$currPos;
            s4 = peg$parseconnection();
            if (s4 !== peg$FAILED) {
              s5 = peg$parseviewGroup();
              if (s5 !== peg$FAILED) {
                s4 = [s4, s5];
                s3 = s4;
              } else {
                peg$currPos = s3;
                s3 = peg$c0;
              }
            } else {
              peg$currPos = s3;
              s3 = peg$c0;
            }
            if (s3 !== peg$FAILED) {
              while (s3 !== peg$FAILED) {
                s2.push(s3);
                s3 = peg$currPos;
                s4 = peg$parseconnection();
                if (s4 !== peg$FAILED) {
                  s5 = peg$parseviewGroup();
                  if (s5 !== peg$FAILED) {
                    s4 = [s4, s5];
                    s3 = s4;
                  } else {
                    peg$currPos = s3;
                    s3 = peg$c0;
                  }
                } else {
                  peg$currPos = s3;
                  s3 = peg$c0;
                }
              }
            } else {
              s2 = peg$c0;
            }
            if (s2 !== peg$FAILED) {
              s3 = peg$parseconnection();
              if (s3 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c38(s2, s3);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parseconnection() {
          var s0, s1, s2, s3;
    
          s0 = peg$currPos;
          if (input.substr(peg$currPos, 2) === peg$c39) {
            s1 = peg$c39;
            peg$currPos += 2;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c40);
            }
          }
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c41();
          }
          s0 = s1;
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            if (input.charCodeAt(peg$currPos) === 45) {
              s1 = peg$c42;
              peg$currPos++;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c43);
              }
            }
            if (s1 !== peg$FAILED) {
              s2 = peg$parsepredicateList();
              if (s2 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 45) {
                  s3 = peg$c42;
                  peg$currPos++;
                } else {
                  s3 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c43);
                  }
                }
                if (s3 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c44(s2);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
            if (s0 === peg$FAILED) {
              s0 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 45) {
                s1 = peg$c42;
                peg$currPos++;
              } else {
                s1 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c43);
                }
              }
              if (s1 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c45();
              }
              s0 = s1;
              if (s0 === peg$FAILED) {
                s0 = peg$currPos;
                if (input.charCodeAt(peg$currPos) === 126) {
                  s1 = peg$c46;
                  peg$currPos++;
                } else {
                  s1 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c47);
                  }
                }
                if (s1 !== peg$FAILED) {
                  s2 = peg$parseequalSpacingPredicateList();
                  if (s2 !== peg$FAILED) {
                    if (input.charCodeAt(peg$currPos) === 126) {
                      s3 = peg$c46;
                      peg$currPos++;
                    } else {
                      s3 = peg$FAILED;
                      if (peg$silentFails === 0) {
                        peg$fail(peg$c47);
                      }
                    }
                    if (s3 !== peg$FAILED) {
                      peg$reportedPos = s0;
                      s1 = peg$c44(s2);
                      s0 = s1;
                    } else {
                      peg$currPos = s0;
                      s0 = peg$c0;
                    }
                  } else {
                    peg$currPos = s0;
                    s0 = peg$c0;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
                if (s0 === peg$FAILED) {
                  s0 = peg$currPos;
                  if (input.charCodeAt(peg$currPos) === 126) {
                    s1 = peg$c46;
                    peg$currPos++;
                  } else {
                    s1 = peg$FAILED;
                    if (peg$silentFails === 0) {
                      peg$fail(peg$c47);
                    }
                  }
                  if (s1 !== peg$FAILED) {
                    peg$reportedPos = s0;
                    s1 = peg$c48();
                  }
                  s0 = s1;
                  if (s0 === peg$FAILED) {
                    s0 = peg$currPos;
                    s1 = peg$c49;
                    if (s1 !== peg$FAILED) {
                      peg$reportedPos = s0;
                      s1 = peg$c50();
                    }
                    s0 = s1;
                  }
                }
              }
            }
          }
    
          return s0;
        }
    
        function peg$parsepredicateList() {
          var s0;
    
          s0 = peg$parsesimplePredicate();
          if (s0 === peg$FAILED) {
            s0 = peg$parsepredicateListWithParens();
          }
    
          return s0;
        }
    
        function peg$parsesimplePredicate() {
          var s0, s1;
    
          s0 = peg$currPos;
          s1 = peg$parsepercentage();
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c51(s1);
          }
          s0 = s1;
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            s1 = peg$parsenumber();
            if (s1 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c52(s1);
            }
            s0 = s1;
          }
    
          return s0;
        }
    
        function peg$parsepredicateListWithParens() {
          var s0, s1, s2, s3, s4, s5, s6;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 40) {
            s1 = peg$c53;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c54);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parsepredicate();
            if (s2 !== peg$FAILED) {
              s3 = [];
              s4 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 44) {
                s5 = peg$c32;
                peg$currPos++;
              } else {
                s5 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c33);
                }
              }
              if (s5 !== peg$FAILED) {
                s6 = peg$parsepredicate();
                if (s6 !== peg$FAILED) {
                  s5 = [s5, s6];
                  s4 = s5;
                } else {
                  peg$currPos = s4;
                  s4 = peg$c0;
                }
              } else {
                peg$currPos = s4;
                s4 = peg$c0;
              }
              while (s4 !== peg$FAILED) {
                s3.push(s4);
                s4 = peg$currPos;
                if (input.charCodeAt(peg$currPos) === 44) {
                  s5 = peg$c32;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c33);
                  }
                }
                if (s5 !== peg$FAILED) {
                  s6 = peg$parsepredicate();
                  if (s6 !== peg$FAILED) {
                    s5 = [s5, s6];
                    s4 = s5;
                  } else {
                    peg$currPos = s4;
                    s4 = peg$c0;
                  }
                } else {
                  peg$currPos = s4;
                  s4 = peg$c0;
                }
              }
              if (s3 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 41) {
                  s4 = peg$c55;
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c56);
                  }
                }
                if (s4 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c57(s2, s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parsepredicate() {
          var s0, s1, s2, s3, s4, s5;
    
          s0 = peg$currPos;
          s1 = peg$parserelation();
          if (s1 === peg$FAILED) {
            s1 = peg$c4;
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parseobjectOfPredicate();
            if (s2 !== peg$FAILED) {
              s3 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 64) {
                s4 = peg$c58;
                peg$currPos++;
              } else {
                s4 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c59);
                }
              }
              if (s4 !== peg$FAILED) {
                s5 = peg$parsepriority();
                if (s5 !== peg$FAILED) {
                  s4 = [s4, s5];
                  s3 = s4;
                } else {
                  peg$currPos = s3;
                  s3 = peg$c0;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$c0;
              }
              if (s3 === peg$FAILED) {
                s3 = peg$c4;
              }
              if (s3 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c60(s1, s2, s3);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parseequalSpacingPredicateList() {
          var s0, s1, s2, s3, s4, s5, s6;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 40) {
            s1 = peg$c53;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c54);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parseequalSpacingPredicate();
            if (s2 !== peg$FAILED) {
              s3 = [];
              s4 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 44) {
                s5 = peg$c32;
                peg$currPos++;
              } else {
                s5 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c33);
                }
              }
              if (s5 !== peg$FAILED) {
                s6 = peg$parseequalSpacingPredicate();
                if (s6 !== peg$FAILED) {
                  s5 = [s5, s6];
                  s4 = s5;
                } else {
                  peg$currPos = s4;
                  s4 = peg$c0;
                }
              } else {
                peg$currPos = s4;
                s4 = peg$c0;
              }
              while (s4 !== peg$FAILED) {
                s3.push(s4);
                s4 = peg$currPos;
                if (input.charCodeAt(peg$currPos) === 44) {
                  s5 = peg$c32;
                  peg$currPos++;
                } else {
                  s5 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c33);
                  }
                }
                if (s5 !== peg$FAILED) {
                  s6 = peg$parseequalSpacingPredicate();
                  if (s6 !== peg$FAILED) {
                    s5 = [s5, s6];
                    s4 = s5;
                  } else {
                    peg$currPos = s4;
                    s4 = peg$c0;
                  }
                } else {
                  peg$currPos = s4;
                  s4 = peg$c0;
                }
              }
              if (s3 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 41) {
                  s4 = peg$c55;
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c56);
                  }
                }
                if (s4 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c57(s2, s3);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parseequalSpacingPredicate() {
          var s0, s1, s2, s3, s4, s5;
    
          s0 = peg$currPos;
          s1 = peg$parserelation();
          if (s1 === peg$FAILED) {
            s1 = peg$c4;
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parseobjectOfPredicate();
            if (s2 !== peg$FAILED) {
              s3 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 64) {
                s4 = peg$c58;
                peg$currPos++;
              } else {
                s4 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c59);
                }
              }
              if (s4 !== peg$FAILED) {
                s5 = peg$parsepriority();
                if (s5 !== peg$FAILED) {
                  s4 = [s4, s5];
                  s3 = s4;
                } else {
                  peg$currPos = s3;
                  s3 = peg$c0;
                }
              } else {
                peg$currPos = s3;
                s3 = peg$c0;
              }
              if (s3 === peg$FAILED) {
                s3 = peg$c4;
              }
              if (s3 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c61(s1, s2, s3);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parserelation() {
          var s0, s1;
    
          s0 = peg$currPos;
          if (input.substr(peg$currPos, 2) === peg$c62) {
            s1 = peg$c62;
            peg$currPos += 2;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c63);
            }
          }
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c64();
          }
          s0 = s1;
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            if (input.substr(peg$currPos, 2) === peg$c65) {
              s1 = peg$c65;
              peg$currPos += 2;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c66);
              }
            }
            if (s1 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c67();
            }
            s0 = s1;
            if (s0 === peg$FAILED) {
              s0 = peg$currPos;
              if (input.substr(peg$currPos, 2) === peg$c68) {
                s1 = peg$c68;
                peg$currPos += 2;
              } else {
                s1 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c69);
                }
              }
              if (s1 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c70();
              }
              s0 = s1;
            }
          }
    
          return s0;
        }
    
        function peg$parseobjectOfPredicate() {
          var s0;
    
          s0 = peg$parsepercentage();
          if (s0 === peg$FAILED) {
            s0 = peg$parseconstant();
            if (s0 === peg$FAILED) {
              s0 = peg$parseviewPredicate();
            }
          }
    
          return s0;
        }
    
        function peg$parsepriority() {
          var s0, s1, s2;
    
          s0 = peg$currPos;
          s1 = [];
          if (peg$c71.test(input.charAt(peg$currPos))) {
            s2 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s2 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c72);
            }
          }
          if (s2 !== peg$FAILED) {
            while (s2 !== peg$FAILED) {
              s1.push(s2);
              if (peg$c71.test(input.charAt(peg$currPos))) {
                s2 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s2 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c72);
                }
              }
            }
          } else {
            s1 = peg$c0;
          }
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c73(s1);
          }
          s0 = s1;
    
          return s0;
        }
    
        function peg$parseconstant() {
          var s0, s1, s2;
    
          s0 = peg$currPos;
          s1 = peg$parsenumber();
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c74(s1);
          }
          s0 = s1;
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            if (input.charCodeAt(peg$currPos) === 45) {
              s1 = peg$c42;
              peg$currPos++;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c43);
              }
            }
            if (s1 !== peg$FAILED) {
              s2 = peg$parsenumber();
              if (s2 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c75(s2);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
            if (s0 === peg$FAILED) {
              s0 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 43) {
                s1 = peg$c76;
                peg$currPos++;
              } else {
                s1 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c77);
                }
              }
              if (s1 !== peg$FAILED) {
                s2 = peg$parsenumber();
                if (s2 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c74(s2);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            }
          }
    
          return s0;
        }
    
        function peg$parsepercentage() {
          var s0, s1, s2, s3;
    
          s0 = peg$currPos;
          s1 = peg$parsenumber();
          if (s1 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 37) {
              s2 = peg$c78;
              peg$currPos++;
            } else {
              s2 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c79);
              }
            }
            if (s2 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c80(s1);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            if (input.charCodeAt(peg$currPos) === 45) {
              s1 = peg$c42;
              peg$currPos++;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c43);
              }
            }
            if (s1 !== peg$FAILED) {
              s2 = peg$parsenumber();
              if (s2 !== peg$FAILED) {
                if (input.charCodeAt(peg$currPos) === 37) {
                  s3 = peg$c78;
                  peg$currPos++;
                } else {
                  s3 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c79);
                  }
                }
                if (s3 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c81(s2);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
            if (s0 === peg$FAILED) {
              s0 = peg$currPos;
              if (input.charCodeAt(peg$currPos) === 43) {
                s1 = peg$c76;
                peg$currPos++;
              } else {
                s1 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c77);
                }
              }
              if (s1 !== peg$FAILED) {
                s2 = peg$parsenumber();
                if (s2 !== peg$FAILED) {
                  if (input.charCodeAt(peg$currPos) === 37) {
                    s3 = peg$c78;
                    peg$currPos++;
                  } else {
                    s3 = peg$FAILED;
                    if (peg$silentFails === 0) {
                      peg$fail(peg$c79);
                    }
                  }
                  if (s3 !== peg$FAILED) {
                    peg$reportedPos = s0;
                    s1 = peg$c80(s2);
                    s0 = s1;
                  } else {
                    peg$currPos = s0;
                    s0 = peg$c0;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            }
          }
    
          return s0;
        }
    
        function peg$parseviewPredicate() {
          var s0, s1, s2, s3, s4;
    
          s0 = peg$currPos;
          s1 = peg$parseviewName();
          if (s1 !== peg$FAILED) {
            s2 = peg$parseattribute();
            if (s2 === peg$FAILED) {
              s2 = peg$c4;
            }
            if (s2 !== peg$FAILED) {
              s3 = peg$parsemultiplier();
              if (s3 === peg$FAILED) {
                s3 = peg$c4;
              }
              if (s3 !== peg$FAILED) {
                s4 = peg$parseconstantExpr();
                if (s4 === peg$FAILED) {
                  s4 = peg$c4;
                }
                if (s4 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c82(s1, s2, s3, s4);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parseattribute() {
          var s0, s1;
    
          s0 = peg$currPos;
          if (input.substr(peg$currPos, 5) === peg$c83) {
            s1 = peg$c83;
            peg$currPos += 5;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c84);
            }
          }
          if (s1 !== peg$FAILED) {
            peg$reportedPos = s0;
            s1 = peg$c85();
          }
          s0 = s1;
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            if (input.substr(peg$currPos, 6) === peg$c86) {
              s1 = peg$c86;
              peg$currPos += 6;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c87);
              }
            }
            if (s1 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c88();
            }
            s0 = s1;
            if (s0 === peg$FAILED) {
              s0 = peg$currPos;
              if (input.substr(peg$currPos, 4) === peg$c89) {
                s1 = peg$c89;
                peg$currPos += 4;
              } else {
                s1 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c90);
                }
              }
              if (s1 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c91();
              }
              s0 = s1;
              if (s0 === peg$FAILED) {
                s0 = peg$currPos;
                if (input.substr(peg$currPos, 7) === peg$c92) {
                  s1 = peg$c92;
                  peg$currPos += 7;
                } else {
                  s1 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c93);
                  }
                }
                if (s1 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c94();
                }
                s0 = s1;
                if (s0 === peg$FAILED) {
                  s0 = peg$currPos;
                  if (input.substr(peg$currPos, 6) === peg$c95) {
                    s1 = peg$c95;
                    peg$currPos += 6;
                  } else {
                    s1 = peg$FAILED;
                    if (peg$silentFails === 0) {
                      peg$fail(peg$c96);
                    }
                  }
                  if (s1 !== peg$FAILED) {
                    peg$reportedPos = s0;
                    s1 = peg$c97();
                  }
                  s0 = s1;
                  if (s0 === peg$FAILED) {
                    s0 = peg$currPos;
                    if (input.substr(peg$currPos, 7) === peg$c98) {
                      s1 = peg$c98;
                      peg$currPos += 7;
                    } else {
                      s1 = peg$FAILED;
                      if (peg$silentFails === 0) {
                        peg$fail(peg$c99);
                      }
                    }
                    if (s1 !== peg$FAILED) {
                      peg$reportedPos = s0;
                      s1 = peg$c100();
                    }
                    s0 = s1;
                    if (s0 === peg$FAILED) {
                      s0 = peg$currPos;
                      if (input.substr(peg$currPos, 8) === peg$c101) {
                        s1 = peg$c101;
                        peg$currPos += 8;
                      } else {
                        s1 = peg$FAILED;
                        if (peg$silentFails === 0) {
                          peg$fail(peg$c102);
                        }
                      }
                      if (s1 !== peg$FAILED) {
                        peg$reportedPos = s0;
                        s1 = peg$c103();
                      }
                      s0 = s1;
                      if (s0 === peg$FAILED) {
                        s0 = peg$currPos;
                        if (input.substr(peg$currPos, 8) === peg$c104) {
                          s1 = peg$c104;
                          peg$currPos += 8;
                        } else {
                          s1 = peg$FAILED;
                          if (peg$silentFails === 0) {
                            peg$fail(peg$c105);
                          }
                        }
                        if (s1 !== peg$FAILED) {
                          peg$reportedPos = s0;
                          s1 = peg$c106();
                        }
                        s0 = s1;
                      }
                    }
                  }
                }
              }
            }
          }
    
          return s0;
        }
    
        function peg$parsemultiplier() {
          var s0, s1, s2;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 47) {
            s1 = peg$c107;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c108);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parsenumber();
            if (s2 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c109(s2);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            if (input.substr(peg$currPos, 2) === peg$c110) {
              s1 = peg$c110;
              peg$currPos += 2;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c111);
              }
            }
            if (s1 !== peg$FAILED) {
              s2 = peg$parsenumber();
              if (s2 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c109(s2);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
            if (s0 === peg$FAILED) {
              s0 = peg$currPos;
              if (input.substr(peg$currPos, 2) === peg$c112) {
                s1 = peg$c112;
                peg$currPos += 2;
              } else {
                s1 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c113);
                }
              }
              if (s1 !== peg$FAILED) {
                s2 = peg$parsenumber();
                if (s2 !== peg$FAILED) {
                  peg$reportedPos = s0;
                  s1 = peg$c114(s2);
                  s0 = s1;
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
              if (s0 === peg$FAILED) {
                s0 = peg$currPos;
                if (input.charCodeAt(peg$currPos) === 42) {
                  s1 = peg$c115;
                  peg$currPos++;
                } else {
                  s1 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c116);
                  }
                }
                if (s1 !== peg$FAILED) {
                  s2 = peg$parsenumber();
                  if (s2 !== peg$FAILED) {
                    peg$reportedPos = s0;
                    s1 = peg$c117(s2);
                    s0 = s1;
                  } else {
                    peg$currPos = s0;
                    s0 = peg$c0;
                  }
                } else {
                  peg$currPos = s0;
                  s0 = peg$c0;
                }
                if (s0 === peg$FAILED) {
                  s0 = peg$currPos;
                  if (input.substr(peg$currPos, 2) === peg$c118) {
                    s1 = peg$c118;
                    peg$currPos += 2;
                  } else {
                    s1 = peg$FAILED;
                    if (peg$silentFails === 0) {
                      peg$fail(peg$c119);
                    }
                  }
                  if (s1 !== peg$FAILED) {
                    s2 = peg$parsenumber();
                    if (s2 !== peg$FAILED) {
                      peg$reportedPos = s0;
                      s1 = peg$c117(s2);
                      s0 = s1;
                    } else {
                      peg$currPos = s0;
                      s0 = peg$c0;
                    }
                  } else {
                    peg$currPos = s0;
                    s0 = peg$c0;
                  }
                  if (s0 === peg$FAILED) {
                    s0 = peg$currPos;
                    if (input.substr(peg$currPos, 2) === peg$c120) {
                      s1 = peg$c120;
                      peg$currPos += 2;
                    } else {
                      s1 = peg$FAILED;
                      if (peg$silentFails === 0) {
                        peg$fail(peg$c121);
                      }
                    }
                    if (s1 !== peg$FAILED) {
                      s2 = peg$parsenumber();
                      if (s2 !== peg$FAILED) {
                        peg$reportedPos = s0;
                        s1 = peg$c122(s2);
                        s0 = s1;
                      } else {
                        peg$currPos = s0;
                        s0 = peg$c0;
                      }
                    } else {
                      peg$currPos = s0;
                      s0 = peg$c0;
                    }
                  }
                }
              }
            }
          }
    
          return s0;
        }
    
        function peg$parseconstantExpr() {
          var s0, s1, s2;
    
          s0 = peg$currPos;
          if (input.charCodeAt(peg$currPos) === 45) {
            s1 = peg$c42;
            peg$currPos++;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c43);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = peg$parsenumber();
            if (s2 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c122(s2);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            if (input.charCodeAt(peg$currPos) === 43) {
              s1 = peg$c76;
              peg$currPos++;
            } else {
              s1 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c77);
              }
            }
            if (s1 !== peg$FAILED) {
              s2 = peg$parsenumber();
              if (s2 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c117(s2);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          }
    
          return s0;
        }
    
        function peg$parseviewNameRange() {
          var s0, s1, s2, s3, s4;
    
          s0 = peg$currPos;
          s1 = peg$currPos;
          s2 = [];
          if (peg$c123.test(input.charAt(peg$currPos))) {
            s3 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s3 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c124);
            }
          }
          if (s3 !== peg$FAILED) {
            while (s3 !== peg$FAILED) {
              s2.push(s3);
              if (peg$c123.test(input.charAt(peg$currPos))) {
                s3 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s3 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c124);
                }
              }
            }
          } else {
            s2 = peg$c0;
          }
          if (s2 !== peg$FAILED) {
            s2 = input.substring(s1, peg$currPos);
          }
          s1 = s2;
          if (s1 !== peg$FAILED) {
            s2 = peg$currPos;
            s3 = [];
            if (peg$c125.test(input.charAt(peg$currPos))) {
              s4 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s4 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c126);
              }
            }
            while (s4 !== peg$FAILED) {
              s3.push(s4);
              if (peg$c125.test(input.charAt(peg$currPos))) {
                s4 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s4 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c126);
                }
              }
            }
            if (s3 !== peg$FAILED) {
              s3 = input.substring(s2, peg$currPos);
            }
            s2 = s3;
            if (s2 !== peg$FAILED) {
              s3 = peg$parserange();
              if (s3 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c127(s1, s2, s3);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            s1 = peg$currPos;
            s2 = [];
            if (peg$c123.test(input.charAt(peg$currPos))) {
              s3 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s3 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c124);
              }
            }
            if (s3 !== peg$FAILED) {
              while (s3 !== peg$FAILED) {
                s2.push(s3);
                if (peg$c123.test(input.charAt(peg$currPos))) {
                  s3 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s3 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c124);
                  }
                }
              }
            } else {
              s2 = peg$c0;
            }
            if (s2 !== peg$FAILED) {
              s2 = input.substring(s1, peg$currPos);
            }
            s1 = s2;
            if (s1 !== peg$FAILED) {
              s2 = peg$currPos;
              s3 = [];
              if (peg$c125.test(input.charAt(peg$currPos))) {
                s4 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s4 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c126);
                }
              }
              while (s4 !== peg$FAILED) {
                s3.push(s4);
                if (peg$c125.test(input.charAt(peg$currPos))) {
                  s4 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s4 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c126);
                  }
                }
              }
              if (s3 !== peg$FAILED) {
                s3 = input.substring(s2, peg$currPos);
              }
              s2 = s3;
              if (s2 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c128(s1, s2);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          }
    
          return s0;
        }
    
        function peg$parseviewName() {
          var s0, s1, s2, s3, s4;
    
          s0 = peg$currPos;
          s1 = peg$currPos;
          s2 = [];
          if (peg$c123.test(input.charAt(peg$currPos))) {
            s3 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s3 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c124);
            }
          }
          if (s3 !== peg$FAILED) {
            while (s3 !== peg$FAILED) {
              s2.push(s3);
              if (peg$c123.test(input.charAt(peg$currPos))) {
                s3 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s3 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c124);
                }
              }
            }
          } else {
            s2 = peg$c0;
          }
          if (s2 !== peg$FAILED) {
            s2 = input.substring(s1, peg$currPos);
          }
          s1 = s2;
          if (s1 !== peg$FAILED) {
            s2 = peg$currPos;
            s3 = [];
            if (peg$c125.test(input.charAt(peg$currPos))) {
              s4 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s4 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c126);
              }
            }
            while (s4 !== peg$FAILED) {
              s3.push(s4);
              if (peg$c125.test(input.charAt(peg$currPos))) {
                s4 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s4 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c126);
                }
              }
            }
            if (s3 !== peg$FAILED) {
              s3 = input.substring(s2, peg$currPos);
            }
            s2 = s3;
            if (s2 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c128(s1, s2);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parserange() {
          var s0, s1, s2, s3;
    
          s0 = peg$currPos;
          if (input.substr(peg$currPos, 2) === peg$c129) {
            s1 = peg$c129;
            peg$currPos += 2;
          } else {
            s1 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c130);
            }
          }
          if (s1 !== peg$FAILED) {
            s2 = [];
            if (peg$c71.test(input.charAt(peg$currPos))) {
              s3 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s3 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c72);
              }
            }
            if (s3 !== peg$FAILED) {
              while (s3 !== peg$FAILED) {
                s2.push(s3);
                if (peg$c71.test(input.charAt(peg$currPos))) {
                  s3 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s3 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c72);
                  }
                }
              }
            } else {
              s2 = peg$c0;
            }
            if (s2 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c131(s2);
              s0 = s1;
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
    
          return s0;
        }
    
        function peg$parsenumber() {
          var s0, s1, s2, s3, s4;
    
          s0 = peg$currPos;
          s1 = [];
          if (peg$c71.test(input.charAt(peg$currPos))) {
            s2 = input.charAt(peg$currPos);
            peg$currPos++;
          } else {
            s2 = peg$FAILED;
            if (peg$silentFails === 0) {
              peg$fail(peg$c72);
            }
          }
          if (s2 !== peg$FAILED) {
            while (s2 !== peg$FAILED) {
              s1.push(s2);
              if (peg$c71.test(input.charAt(peg$currPos))) {
                s2 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s2 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c72);
                }
              }
            }
          } else {
            s1 = peg$c0;
          }
          if (s1 !== peg$FAILED) {
            if (input.charCodeAt(peg$currPos) === 46) {
              s2 = peg$c132;
              peg$currPos++;
            } else {
              s2 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c133);
              }
            }
            if (s2 !== peg$FAILED) {
              s3 = [];
              if (peg$c71.test(input.charAt(peg$currPos))) {
                s4 = input.charAt(peg$currPos);
                peg$currPos++;
              } else {
                s4 = peg$FAILED;
                if (peg$silentFails === 0) {
                  peg$fail(peg$c72);
                }
              }
              if (s4 !== peg$FAILED) {
                while (s4 !== peg$FAILED) {
                  s3.push(s4);
                  if (peg$c71.test(input.charAt(peg$currPos))) {
                    s4 = input.charAt(peg$currPos);
                    peg$currPos++;
                  } else {
                    s4 = peg$FAILED;
                    if (peg$silentFails === 0) {
                      peg$fail(peg$c72);
                    }
                  }
                }
              } else {
                s3 = peg$c0;
              }
              if (s3 !== peg$FAILED) {
                peg$reportedPos = s0;
                s1 = peg$c134(s1, s3);
                s0 = s1;
              } else {
                peg$currPos = s0;
                s0 = peg$c0;
              }
            } else {
              peg$currPos = s0;
              s0 = peg$c0;
            }
          } else {
            peg$currPos = s0;
            s0 = peg$c0;
          }
          if (s0 === peg$FAILED) {
            s0 = peg$currPos;
            s1 = [];
            if (peg$c71.test(input.charAt(peg$currPos))) {
              s2 = input.charAt(peg$currPos);
              peg$currPos++;
            } else {
              s2 = peg$FAILED;
              if (peg$silentFails === 0) {
                peg$fail(peg$c72);
              }
            }
            if (s2 !== peg$FAILED) {
              while (s2 !== peg$FAILED) {
                s1.push(s2);
                if (peg$c71.test(input.charAt(peg$currPos))) {
                  s2 = input.charAt(peg$currPos);
                  peg$currPos++;
                } else {
                  s2 = peg$FAILED;
                  if (peg$silentFails === 0) {
                    peg$fail(peg$c72);
                  }
                }
              }
            } else {
              s1 = peg$c0;
            }
            if (s1 !== peg$FAILED) {
              peg$reportedPos = s0;
              s1 = peg$c135(s1);
            }
            s0 = s1;
          }
    
          return s0;
        }
    
        function extend(dst) {
          for (var i = 1; i < arguments.length; i++) {
            for (var k in arguments[i]) {
              dst[k] = arguments[i][k];
            }
          }
          return dst;
        }
    
        peg$result = peg$startRuleFunction();
    
        if (peg$result !== peg$FAILED && peg$currPos === input.length) {
          return peg$result;
        } else {
          if (peg$result !== peg$FAILED && peg$currPos < input.length) {
            peg$fail({ type: "end", description: "end of input" });
          }
    
          throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
        }
      }
    
      return {
        SyntaxError: SyntaxError,
        parse: parse
      };
    }();
    
    var Orientation = {
      HORIZONTAL: 1,
      VERTICAL: 2,
      ZINDEX: 4
    };
    
    /**
     * Helper function that inserts equal spacers (~).
     * @private
     */
    function _processEqualSpacer(context, stackView) {
    
      // Determine unique name for the spacer
      context.equalSpacerIndex = context.equalSpacerIndex || 1;
      var name = '_~' + context.lineIndex + ':' + context.equalSpacerIndex + '~';
      if (context.equalSpacerIndex > 1) {
    
        // Ensure that all spacers have the same width/height
        context.constraints.push({
          view1: '_~' + context.lineIndex + ':1~',
          attr1: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
          relation: context.relation.relation || Relation.EQU,
          view2: name,
          attr2: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
          priority: context.relation.priority
        });
      }
      context.equalSpacerIndex++;
    
      // Enforce view/proportional width/height
      if (context.relation.view || context.relation.multiplier && context.relation.multiplier !== 1) {
        context.constraints.push({
          view1: name,
          attr1: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
          relation: context.relation.relation || Relation.EQU,
          view2: context.relation.view,
          attr2: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
          priority: context.relation.priority,
          multiplier: context.relation.multiplier
        });
        context.relation.multiplier = undefined;
      } else if (context.relation.constant) {
        context.constraints.push({
          view1: name,
          attr1: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
          relation: Relation.EQU,
          view2: null,
          attr2: Attribute.CONST,
          priority: context.relation.priority,
          constant: context.relation.constant
        });
        context.relation.constant = undefined;
      }
    
      // Add constraint
      for (var i = 0; i < context.prevViews.length; i++) {
        var prevView = context.prevViews[i];
        switch (context.orientation) {
          case Orientation.HORIZONTAL:
            context.prevAttr = prevView !== stackView ? Attribute.RIGHT : Attribute.LEFT;
            context.curAttr = Attribute.LEFT;
            break;
          case Orientation.VERTICAL:
            context.prevAttr = prevView !== stackView ? Attribute.BOTTOM : Attribute.TOP;
            context.curAttr = Attribute.TOP;
            break;
          case Orientation.ZINDEX:
            context.prevAttr = Attribute.ZINDEX;
            context.curAttr = Attribute.ZINDEX;
            context.relation.constant = prevView !== stackView ? 'default' : 0;
            break;
        }
        context.constraints.push({
          view1: prevView,
          attr1: context.prevAttr,
          relation: context.relation.relation,
          view2: name,
          attr2: context.curAttr,
          priority: context.relation.priority
        });
      }
      context.prevViews = [name];
    }
    
    /**
     * Helper function that inserts proportional spacers (-12%-).
     * @private
     */
    function _processProportionalSpacer(context, stackView) {
      context.proportionalSpacerIndex = context.proportionalSpacerIndex || 1;
      var name = '_-' + context.lineIndex + ':' + context.proportionalSpacerIndex + '-';
      context.proportionalSpacerIndex++;
      context.constraints.push({
        view1: name,
        attr1: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
        relation: context.relation.relation || Relation.EQU,
        view2: context.relation.view, // or relative to the stackView... food for thought
        attr2: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
        priority: context.relation.priority,
        multiplier: context.relation.multiplier
      });
      context.relation.multiplier = undefined;
    
      // Add constraint
      for (var i = 0; i < context.prevViews.length; i++) {
        var prevView = context.prevViews[i];
        switch (context.orientation) {
          case Orientation.HORIZONTAL:
            context.prevAttr = prevView !== stackView ? Attribute.RIGHT : Attribute.LEFT;
            context.curAttr = Attribute.LEFT;
            break;
          case Orientation.VERTICAL:
            context.prevAttr = prevView !== stackView ? Attribute.BOTTOM : Attribute.TOP;
            context.curAttr = Attribute.TOP;
            break;
          case Orientation.ZINDEX:
            context.prevAttr = Attribute.ZINDEX;
            context.curAttr = Attribute.ZINDEX;
            context.relation.constant = prevView !== stackView ? 'default' : 0;
            break;
        }
        context.constraints.push({
          view1: prevView,
          attr1: context.prevAttr,
          relation: context.relation.relation,
          view2: name,
          attr2: context.curAttr,
          priority: context.relation.priority
        });
      }
      context.prevViews = [name];
    }
    
    /**
     * In case of a stack-view, set constraints for opposite orientations
     * @private
     */
    function _processStackView(context, name, subView) {
      var viewName = void 0;
      for (var orientation = 1; orientation <= 4; orientation *= 2) {
        if (subView.orientations & orientation && subView.stack.orientation !== orientation && !(subView.stack.processedOrientations & orientation)) {
          subView.stack.processedOrientations = subView.stack.processedOrientations | orientation;
          viewName = viewName || {
            name: name,
            type: 'stack'
          };
          for (var i = 0, j = subView.stack.subViews.length; i < j; i++) {
            if (orientation === Orientation.ZINDEX) {
              context.constraints.push({
                view1: viewName,
                attr1: Attribute.ZINDEX,
                relation: Relation.EQU,
                view2: subView.stack.subViews[i],
                attr2: Attribute.ZINDEX
              });
            } else {
              context.constraints.push({
                view1: viewName,
                attr1: orientation === Orientation.VERTICAL ? Attribute.HEIGHT : Attribute.WIDTH,
                relation: Relation.EQU,
                view2: subView.stack.subViews[i],
                attr2: orientation === Orientation.VERTICAL ? Attribute.HEIGHT : Attribute.WIDTH
              });
              context.constraints.push({
                view1: viewName,
                attr1: orientation === Orientation.VERTICAL ? Attribute.TOP : Attribute.LEFT,
                relation: Relation.EQU,
                view2: subView.stack.subViews[i],
                attr2: orientation === Orientation.VERTICAL ? Attribute.TOP : Attribute.LEFT
              });
            }
          }
        }
      }
    }
    
    /**
     * Recursive helper function converts a view-name and a range to a series
     * of view-names (e.g. [child1, child2, child3, ...]).
     * @private
     */
    function _getRange(name, range) {
      if (range === true) {
        range = name.match(/\.\.\d+$/);
        if (range) {
          name = name.substring(0, name.length - range[0].length);
          range = parseInt(range[0].substring(2));
        }
      }
      if (!range) {
        return [name];
      }
      var start = name.match(/\d+$/);
      var res = [];
      var i;
      if (start) {
        name = name.substring(0, name.length - start[0].length);
        for (i = parseInt(start); i <= range; i++) {
          res.push(name + i);
        }
      } else {
        res.push(name);
        for (i = 2; i <= range; i++) {
          res.push(name + i);
        }
      }
      return res;
    }
    
    /**
     * Recursive helper function that processes the cascaded data.
     * @private
     */
    function _processCascade(context, cascade, parentItem) {
      var stackView = parentItem ? parentItem.view : null;
      var subViews = [];
      var curViews = [];
      var subView = void 0;
      if (stackView) {
        cascade.push({ view: stackView });
        curViews.push(stackView);
      }
      for (var i = 0; i < cascade.length; i++) {
        var item = cascade[i];
        if (!Array.isArray(item) && item.hasOwnProperty('view') || Array.isArray(item) && item[0].view && !item[0].relation) {
          var items = Array.isArray(item) ? item : [item];
          for (var z = 0; z < items.length; z++) {
            item = items[z];
            var viewRange = item === ',' ? [] : item.view ? _getRange(item.view, item.range) : [null];
            for (var r = 0; r < viewRange.length; r++) {
              var curView = viewRange[r];
              curViews.push(curView);
    
              //
              // Add this view to the collection of subViews
              //
              if (curView !== stackView) {
                subViews.push(curView);
                subView = context.subViews[curView];
                if (!subView) {
                  subView = { orientations: 0 };
                  context.subViews[curView] = subView;
                }
                subView.orientations = subView.orientations | context.orientation;
                if (subView.stack) {
                  _processStackView(context, curView, subView);
                }
              }
    
              //
              // Process the relationship between this and the previous views
              //
              if (context.prevViews !== undefined && curView !== undefined && context.relation) {
                if (context.relation.relation !== 'none') {
                  for (var p = 0; p < context.prevViews.length; p++) {
                    var prevView = context.prevViews[p];
                    switch (context.orientation) {
                      case Orientation.HORIZONTAL:
                        context.prevAttr = prevView !== stackView ? Attribute.RIGHT : Attribute.LEFT;
                        context.curAttr = curView !== stackView ? Attribute.LEFT : Attribute.RIGHT;
                        break;
                      case Orientation.VERTICAL:
                        context.prevAttr = prevView !== stackView ? Attribute.BOTTOM : Attribute.TOP;
                        context.curAttr = curView !== stackView ? Attribute.TOP : Attribute.BOTTOM;
                        break;
                      case Orientation.ZINDEX:
                        context.prevAttr = Attribute.ZINDEX;
                        context.curAttr = Attribute.ZINDEX;
                        context.relation.constant = !prevView ? 0 : context.relation.constant || 'default';
                        break;
                    }
                    context.constraints.push({
                      view1: prevView,
                      attr1: context.prevAttr,
                      relation: context.relation.relation,
                      view2: curView,
                      attr2: context.curAttr,
                      multiplier: context.relation.multiplier,
                      constant: context.relation.constant === 'default' || !context.relation.constant ? context.relation.constant : -context.relation.constant,
                      priority: context.relation.priority
                    });
                  }
                }
              }
    
              //
              // Process view size constraints
              //
              var constraints = item.constraints;
              if (constraints) {
                for (var n = 0; n < constraints.length; n++) {
                  context.prevAttr = context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT;
                  context.curAttr = constraints[n].view || constraints[n].multiplier ? constraints[n].attribute || context.prevAttr : constraints[n].variable ? Attribute.VARIABLE : Attribute.CONST;
                  context.constraints.push({
                    view1: curView,
                    attr1: context.prevAttr,
                    relation: constraints[n].relation,
                    view2: constraints[n].view,
                    attr2: context.curAttr,
                    multiplier: constraints[n].multiplier,
                    constant: constraints[n].constant,
                    priority: constraints[n].priority
                  });
                }
              }
    
              //
              // Process cascaded data (child stack-views)
              //
              if (item.cascade) {
                _processCascade(context, item.cascade, item);
              }
            }
          }
        } else if (item !== ',') {
          context.prevViews = curViews;
          curViews = [];
          context.relation = item[0];
          if (context.prevViews !== undefined) {
            if (context.relation.equalSpacing) {
              _processEqualSpacer(context, stackView);
            }
            if (context.relation.multiplier) {
              _processProportionalSpacer(context, stackView);
            }
          }
        }
      }
    
      if (stackView) {
        subView = context.subViews[stackView];
        if (!subView) {
          subView = { orientations: context.orientation };
          context.subViews[stackView] = subView;
        } else if (subView.stack) {
          var err = new Error('A stack named "' + stackView + '" has already been created');
          err.column = parentItem.$parserOffset + 1;
          throw err;
        }
        subView.stack = {
          orientation: context.orientation,
          processedOrientations: context.orientation,
          subViews: subViews
        };
        _processStackView(context, stackView, subView);
      }
    }
    
    var metaInfoCategories = ['viewport', 'spacing', 'colors', 'shapes', 'widths', 'heights'];
    
    /**
     * VisualFormat
     *
     * @namespace VisualFormat
     */
    
    var VisualFormat = function () {
      function VisualFormat() {
        _classCallCheck(this, VisualFormat);
      }
    
      _createClass(VisualFormat, null, [{
        key: 'parseLine',
    
    
        /**
         * Parses a single line of vfl into an array of constraint definitions.
         *
         * When the visual-format could not be succesfully parsed an exception is thrown containing
         * additional info about the parse error and column position.
         *
         * @param {String} visualFormat Visual format string (cannot contain line-endings!).
         * @param {Object} [options] Configuration options.
         * @param {Boolean} [options.extended] When set to true uses the extended syntax (default: false).
         * @param {String} [options.outFormat] Output format (`constraints` or `raw`) (default: `constraints`).
         * @param {Number} [options.lineIndex] Line-index used when auto generating equal-spacing constraints.
         * @return {Array} Array of constraint definitions.
         */
        value: function parseLine(visualFormat, options) {
          if (visualFormat.length === 0 || options && options.extended && visualFormat.indexOf('//') === 0) {
            return [];
          }
          var res = options && options.extended ? parserExt.parse(visualFormat) : parser.parse(visualFormat);
          if (options && options.outFormat === 'raw') {
            return [res];
          }
          var context = {
            constraints: [],
            lineIndex: (options ? options.lineIndex : undefined) || 1,
            subViews: (options ? options.subViews : undefined) || {}
          };
          if (res.type === 'attribute') {
            for (var n = 0; n < res.attributes.length; n++) {
              var attr = res.attributes[n];
              for (var m = 0; m < attr.predicates.length; m++) {
                var predicate = attr.predicates[m];
                context.constraints.push({
                  view1: res.view,
                  attr1: attr.attr,
                  relation: predicate.relation,
                  view2: predicate.view,
                  attr2: predicate.attribute || attr.attr,
                  multiplier: predicate.multiplier,
                  constant: predicate.constant,
                  priority: predicate.priority
                });
              }
            }
          } else {
            switch (res.orientation) {
              case 'horizontal':
                context.orientation = Orientation.HORIZONTAL;
                context.horizontal = true;
                _processCascade(context, res.cascade, null);
                break;
              case 'vertical':
                context.orientation = Orientation.VERTICAL;
                _processCascade(context, res.cascade, null);
                break;
              case 'horzvert':
                context.orientation = Orientation.HORIZONTAL;
                context.horizontal = true;
                _processCascade(context, res.cascade, null);
                context = {
                  constraints: context.constraints,
                  lineIndex: context.lineIndex,
                  subViews: context.subViews,
                  orientation: Orientation.VERTICAL
                };
                _processCascade(context, res.cascade, null);
                break;
              case 'zIndex':
                context.orientation = Orientation.ZINDEX;
                _processCascade(context, res.cascade, null);
                break;
            }
          }
          return context.constraints;
        }
    
        /**
         * Parses one or more visual format strings into an array of constraint definitions.
         *
         * When the visual-format could not be succesfully parsed an exception is thrown containing
         * additional info about the parse error and column position.
         *
         * @param {String|Array} visualFormat One or more visual format strings.
         * @param {Object} [options] Configuration options.
         * @param {Boolean} [options.extended] When set to true uses the extended syntax (default: false).
         * @param {Boolean} [options.strict] When set to false trims any leading/trailing spaces and ignores empty lines (default: true).
         * @param {String} [options.lineSeparator] String that defines the end of a line (default `\n`).
         * @param {String} [options.outFormat] Output format (`constraints` or `raw`) (default: `constraints`).
         * @return {Array} Array of constraint definitions.
         */
    
      }, {
        key: 'parse',
        value: function parse(visualFormat, options) {
          var lineSeparator = options && options.lineSeparator ? options.lineSeparator : '\n';
          if (!Array.isArray(visualFormat) && visualFormat.indexOf(lineSeparator) < 0) {
            try {
              return this.parseLine(visualFormat, options);
            } catch (err) {
              err.source = visualFormat;
              throw err;
            }
          }
    
          // Decompose visual-format into an array of strings, and within those strings
          // search for line-endings, and treat each line as a seperate visual-format.
          visualFormat = Array.isArray(visualFormat) ? visualFormat : [visualFormat];
          var lines = void 0;
          var constraints = [];
          var lineIndex = 0;
          var line = void 0;
          var parseOptions = {
            lineIndex: lineIndex,
            extended: options && options.extended,
            strict: options && options.strict !== undefined ? options.strict : true,
            outFormat: options ? options.outFormat : undefined,
            subViews: {}
          };
          try {
            for (var i = 0; i < visualFormat.length; i++) {
              lines = visualFormat[i].split(lineSeparator);
              for (var j = 0; j < lines.length; j++) {
                line = lines[j];
                lineIndex++;
                parseOptions.lineIndex = lineIndex;
                if (!parseOptions.strict) {
                  line = line.trim();
                }
                if (parseOptions.strict || line.length) {
                  constraints = constraints.concat(this.parseLine(line, parseOptions));
                }
              }
            }
          } catch (err) {
            err.source = line;
            err.line = lineIndex;
            throw err;
          }
          return constraints;
        }
    
        /**
         * Parses meta information from the comments in the VFL.
         *
         * Additional meta information can be specified in the comments
         * for previewing and rendering purposes. For instance, the view-port
         * aspect-ratio, sub-view widths and colors, can be specified. The
         * following example renders three colored circles in the visual-format editor:
         *
         * ```vfl
         * //viewport aspect-ratio:3/1 max-height:300
         * //colors red:#FF0000 green:#00FF00 blue:#0000FF
         * //shapes red:circle green:circle blue:circle
         * H:|-[row:[red(green,blue)]-[green]-[blue]]-|
         * V:|[row]|
         * ```
         *
         * Supported categories and properties:
         *
         * |Category|Property|Example|
         * |--------|--------|-------|
         * |`viewport`|`aspect-ratio:{width}/{height}`|`//viewport aspect-ratio:16/9`|
         * ||`width:[{number}/intrinsic]`|`//viewport width:10`|
         * ||`height:[{number}/intrinsic]`|`//viewport height:intrinsic`|
         * ||`min-width:{number}`|
         * ||`max-width:{number}`|
         * ||`min-height:{number}`|
         * ||`max-height:{number}`|
         * |`spacing`|`[{number}/array]`|`//spacing:8` or `//spacing:[10, 20, 5]`|
         * |`widths`|`{view-name}:[{number}/intrinsic]`|`//widths subview1:100`|
         * |`heights`|`{view-name}:[{number}/intrinsic]`|`//heights subview1:intrinsic`|
         * |`colors`|`{view-name}:{color}`|`//colors redview:#FF0000 blueview:#00FF00`|
         * |`shapes`|`{view-name}:[circle/square]`|`//shapes avatar:circle`|
         *
         * @param {String|Array} visualFormat One or more visual format strings.
         * @param {Object} [options] Configuration options.
         * @param {String} [options.lineSeparator] String that defines the end of a line (default `\n`).
         * @param {String} [options.prefix] When specified, also processes the categories using that prefix (e.g. "-dev-viewport max-height:10").
         * @return {Object} meta-info
         */
    
      }, {
        key: 'parseMetaInfo',
        value: function parseMetaInfo(visualFormat, options) {
          var lineSeparator = options && options.lineSeparator ? options.lineSeparator : '\n';
          var prefix = options ? options.prefix : undefined;
          visualFormat = Array.isArray(visualFormat) ? visualFormat : [visualFormat];
          var metaInfo = {};
          var key;
          for (var k = 0; k < visualFormat.length; k++) {
            var lines = visualFormat[k].split(lineSeparator);
            for (var i = 0; i < lines.length; i++) {
              var line = lines[i];
              for (var c = 0; c < metaInfoCategories.length; c++) {
                for (var s = 0; s < (prefix ? 2 : 1); s++) {
                  var category = metaInfoCategories[c];
                  var prefixedCategory = (s === 0 ? '' : prefix) + category;
                  if (line.indexOf('//' + prefixedCategory + ' ') === 0) {
                    var items = line.substring(3 + prefixedCategory.length).split(' ');
                    for (var j = 0; j < items.length; j++) {
                      metaInfo[category] = metaInfo[category] || {};
                      var item = items[j].split(':');
                      var names = _getRange(item[0], true);
                      for (var r = 0; r < names.length; r++) {
                        metaInfo[category][names[r]] = item.length > 1 ? item[1] : '';
                      }
                    }
                  } else if (line.indexOf('//' + prefixedCategory + ':') === 0) {
                    metaInfo[category] = line.substring(3 + prefixedCategory.length);
                  }
                }
              }
            }
          }
          if (metaInfo.viewport) {
            var viewport = metaInfo.viewport;
            var aspectRatio = viewport['aspect-ratio'];
            if (aspectRatio) {
              aspectRatio = aspectRatio.split('/');
              viewport['aspect-ratio'] = parseInt(aspectRatio[0]) / parseInt(aspectRatio[1]);
            }
            if (viewport.height !== undefined) {
              viewport.height = viewport.height === 'intrinsic' ? true : parseInt(viewport.height);
            }
            if (viewport.width !== undefined) {
              viewport.width = viewport.width === 'intrinsic' ? true : parseInt(viewport.width);
            }
            if (viewport['max-height'] !== undefined) {
              viewport['max-height'] = parseInt(viewport['max-height']);
            }
            if (viewport['max-width'] !== undefined) {
              viewport['max-width'] = parseInt(viewport['max-width']);
            }
            if (viewport['min-height'] !== undefined) {
              viewport['min-height'] = parseInt(viewport['min-height']);
            }
            if (viewport['min-width'] !== undefined) {
              viewport['min-width'] = parseInt(viewport['min-width']);
            }
          }
          if (metaInfo.widths) {
            for (key in metaInfo.widths) {
              var width = metaInfo.widths[key] === 'intrinsic' ? true : parseInt(metaInfo.widths[key]);
              metaInfo.widths[key] = width;
              if (width === undefined || isNaN(width)) {
                delete metaInfo.widths[key];
              }
            }
          }
          if (metaInfo.heights) {
            for (key in metaInfo.heights) {
              var height = metaInfo.heights[key] === 'intrinsic' ? true : parseInt(metaInfo.heights[key]);
              metaInfo.heights[key] = height;
              if (height === undefined || isNaN(height)) {
                delete metaInfo.heights[key];
              }
            }
          }
          if (metaInfo.spacing) {
            var value = JSON.parse(metaInfo.spacing);
            metaInfo.spacing = value;
            if (Array.isArray(value)) {
              for (var sIdx = 0, len = value.length; sIdx < len; sIdx++) {
                if (isNaN(value[sIdx])) {
                  delete metaInfo.spacing;
                  break;
                }
              }
            } else if (value === undefined || isNaN(value)) {
              delete metaInfo.spacing;
            }
          }
          return metaInfo;
        }
      }]);
    
      return VisualFormat;
    }();
    
    /**
     * A SubView is automatically generated when constraints are added to a View.
     *
     * @namespace SubView
     */
    
    
    var SubView = function () {
      function SubView(options) {
        _classCallCheck(this, SubView);
    
        this._name = options.name;
        this._type = options.type;
        this._solver = options.solver;
        this._attr = {};
        if (!options.name) {
          if (true) {
            this._attr[Attribute.LEFT] = new c.Variable();
            this._solver.addConstraint(new c.StayConstraint(this._attr[Attribute.LEFT], c.Strength.required));
            this._attr[Attribute.TOP] = new c.Variable();
            this._solver.addConstraint(new c.StayConstraint(this._attr[Attribute.TOP], c.Strength.required));
            this._attr[Attribute.ZINDEX] = new c.Variable();
            this._solver.addConstraint(new c.StayConstraint(this._attr[Attribute.ZINDEX], c.Strength.required));
          } else {
            this._attr[Attribute.LEFT] = new kiwi.Variable();
            this._solver.addConstraint(new kiwi.Constraint(this._attr[Attribute.LEFT], kiwi.Operator.Eq, 0));
            this._attr[Attribute.TOP] = new kiwi.Variable();
            this._solver.addConstraint(new kiwi.Constraint(this._attr[Attribute.TOP], kiwi.Operator.Eq, 0));
            this._attr[Attribute.ZINDEX] = new kiwi.Variable();
            this._solver.addConstraint(new kiwi.Constraint(this._attr[Attribute.ZINDEX], kiwi.Operator.Eq, 0));
          }
        }
      }
    
      _createClass(SubView, [{
        key: 'toJSON',
        value: function toJSON() {
          return {
            name: this.name,
            left: this.left,
            top: this.top,
            width: this.width,
            height: this.height
          };
        }
      }, {
        key: 'toString',
        value: function toString() {
          JSON.stringify(this.toJSON(), undefined, 2);
        }
    
        /**
         * Name of the sub-view.
         * @readonly
         * @type {String}
         */
    
      }, {
        key: 'getValue',
    
    
        /**
         * Gets the value of one of the attributes.
         *
         * @param {String|Attribute} attr Attribute name (e.g. 'right', 'centerY', Attribute.TOP).
         * @return {Number} value or `undefined`
         */
        value: function getValue(attr) {
          return this._attr[attr] ? this._attr[attr].value() : undefined;
        }
    
        /**
         * @private
         */
    
      }, {
        key: '_getAttr',
        value: function _getAttr(attr) {
          if (this._attr[attr]) {
            return this._attr[attr];
          }
          this._attr[attr] = true ? new c.Variable() : new kiwi.Variable();
          switch (attr) {
            case Attribute.RIGHT:
              this._getAttr(Attribute.LEFT);
              this._getAttr(Attribute.WIDTH);
              if (true) {
                this._solver.addConstraint(new c.Equation(this._attr[attr], c.plus(this._attr[Attribute.LEFT], this._attr[Attribute.WIDTH])));
              } else {
                this._solver.addConstraint(new kiwi.Constraint(this._attr[attr], kiwi.Operator.Eq, this._attr[Attribute.LEFT].plus(this._attr[Attribute.WIDTH])));
              }
              break;
            case Attribute.BOTTOM:
              this._getAttr(Attribute.TOP);
              this._getAttr(Attribute.HEIGHT);
              if (true) {
                this._solver.addConstraint(new c.Equation(this._attr[attr], c.plus(this._attr[Attribute.TOP], this._attr[Attribute.HEIGHT])));
              } else {
                this._solver.addConstraint(new kiwi.Constraint(this._attr[attr], kiwi.Operator.Eq, this._attr[Attribute.TOP].plus(this._attr[Attribute.HEIGHT])));
              }
              break;
            case Attribute.CENTERX:
              this._getAttr(Attribute.LEFT);
              this._getAttr(Attribute.WIDTH);
              if (true) {
                this._solver.addConstraint(new c.Equation(this._attr[attr], c.plus(this._attr[Attribute.LEFT], c.divide(this._attr[Attribute.WIDTH], 2))));
              } else {
                this._solver.addConstraint(new kiwi.Constraint(this._attr[attr], kiwi.Operator.Eq, this._attr[Attribute.LEFT].plus(this._attr[Attribute.WIDTH].divide(2))));
              }
              break;
            case Attribute.CENTERY:
              this._getAttr(Attribute.TOP);
              this._getAttr(Attribute.HEIGHT);
              if (true) {
                this._solver.addConstraint(new c.Equation(this._attr[attr], c.plus(this._attr[Attribute.TOP], c.divide(this._attr[Attribute.HEIGHT], 2))));
              } else {
                this._solver.addConstraint(new kiwi.Constraint(this._attr[attr], kiwi.Operator.Eq, this._attr[Attribute.TOP].plus(this._attr[Attribute.HEIGHT].divide(2))));
              }
              break;
          }
          if (!true) {
            this._solver.updateVariables();
          }
          return this._attr[attr];
        }
    
        /**
         * @private
         */
    
      }, {
        key: '_getAttrValue',
        value: function _getAttrValue(attr) {
          if (true) {
            return this._getAttr(attr).value;
          } else {
            return this._getAttr(attr).value();
          }
        }
      }, {
        key: 'name',
        get: function get() {
          return this._name;
        }
    
        /**
         * Left value (`Attribute.LEFT`).
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'left',
        get: function get() {
          return this._getAttrValue(Attribute.LEFT);
        }
    
        /**
         * Right value (`Attribute.RIGHT`).
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'right',
        get: function get() {
          return this._getAttrValue(Attribute.RIGHT);
        }
    
        /**
         * Width value (`Attribute.WIDTH`).
         * @type {Number}
         */
    
      }, {
        key: 'width',
        get: function get() {
          return this._getAttrValue(Attribute.WIDTH);
        }
    
        /**
         * Height value (`Attribute.HEIGHT`).
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'height',
        get: function get() {
          return this._getAttrValue(Attribute.HEIGHT);
        }
    
        /**
         * Intrinsic width of the sub-view.
         *
         * Use this property to explicitely set the width of the sub-view, e.g.:
         * ```javascript
         * var view = new AutoLayout.View(AutoLayout.VisualFormat.parse('|[child1][child2]|'), {
         *   width: 500
         * });
         * view.subViews.child1.intrinsicWidth = 100;
         * console.log('child2 width: ' + view.subViews.child2.width); // 400
         * ```
         *
         * @type {Number}
         */
    
      }, {
        key: 'intrinsicWidth',
        get: function get() {
          return this._intrinsicWidth;
        },
        set: function set(value) {
          if (value !== undefined && value !== this._intrinsicWidth) {
            var attr = this._getAttr(Attribute.WIDTH);
            if (this._intrinsicWidth === undefined) {
              if (true) {
                this._solver.addEditVar(attr, new c.Strength('required', this._name ? 998 : 999, 1000, 1000));
              } else {
                this._solver.addEditVariable(attr, kiwi.Strength.create(this._name ? 998 : 999, 1000, 1000));
              }
            }
            this._intrinsicWidth = value;
            this._solver.suggestValue(attr, value);
            if (true) {
              this._solver.resolve();
            } else {
              this._solver.updateVariables();
            }
          }
        }
    
        /**
         * Intrinsic height of the sub-view.
         *
         * See `intrinsicWidth`.
         *
         * @type {Number}
         */
    
      }, {
        key: 'intrinsicHeight',
        get: function get() {
          return this._intrinsicHeight;
        },
        set: function set(value) {
          if (value !== undefined && value !== this._intrinsicHeight) {
            var attr = this._getAttr(Attribute.HEIGHT);
            if (this._intrinsicHeight === undefined) {
              if (true) {
                this._solver.addEditVar(attr, new c.Strength('required', this._name ? 998 : 999, 1000, 1000));
              } else {
                this._solver.addEditVariable(attr, kiwi.Strength.create(this._name ? 998 : 999, 1000, 1000));
              }
            }
            this._intrinsicHeight = value;
            this._solver.suggestValue(attr, value);
            if (true) {
              this._solver.resolve();
            } else {
              this._solver.updateVariables();
            }
          }
        }
    
        /**
         * Top value (`Attribute.TOP`).
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'top',
        get: function get() {
          return this._getAttrValue(Attribute.TOP);
        }
    
        /**
         * Bottom value (`Attribute.BOTTOM`).
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'bottom',
        get: function get() {
          return this._getAttrValue(Attribute.BOTTOM);
        }
    
        /**
         * Horizontal center (`Attribute.CENTERX`).
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'centerX',
        get: function get() {
          return this._getAttrValue(Attribute.CENTERX);
        }
    
        /**
         * Vertical center (`Attribute.CENTERY`).
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'centerY',
        get: function get() {
          return this._getAttrValue(Attribute.CENTERY);
        }
    
        /**
         * Z-index (`Attribute.ZINDEX`).
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'zIndex',
        get: function get() {
          return this._getAttrValue(Attribute.ZINDEX);
        }
    
        /**
         * Returns the type of the sub-view.
         * @readonly
         * @type {String}
         */
    
      }, {
        key: 'type',
        get: function get() {
          return this._type;
        }
      }]);
    
      return SubView;
    }();
    
    var defaultPriorityStrength = true ? new c.Strength('defaultPriority', 0, 1000, 1000) : kiwi.Strength.create(0, 1000, 1000);
    
    function _getConst(name, value) {
      if (true) {
        var vr = new c.Variable({ value: value });
        this._solver.addConstraint(new c.StayConstraint(vr, c.Strength.required, 0));
        return vr;
      } else {
        var _vr = new kiwi.Variable();
        this._solver.addConstraint(new kiwi.Constraint(_vr, kiwi.Operator.Eq, value));
        return _vr;
      }
    }
    
    function _getSubView(viewName) {
      if (!viewName) {
        return this._parentSubView;
      } else if (viewName.name) {
        this._subViews[viewName.name] = this._subViews[viewName.name] || new SubView({
          name: viewName.name,
          solver: this._solver
        });
        this._subViews[viewName.name]._type = this._subViews[viewName.name]._type || viewName.type;
        return this._subViews[viewName.name];
      } else {
        this._subViews[viewName] = this._subViews[viewName] || new SubView({
          name: viewName,
          solver: this._solver
        });
        return this._subViews[viewName];
      }
    }
    
    function _getSpacing(constraint) {
      var index = 4;
      if (!constraint.view1 && constraint.attr1 === 'left') {
        index = 3;
      } else if (!constraint.view1 && constraint.attr1 === 'top') {
        index = 0;
      } else if (!constraint.view2 && constraint.attr2 === 'right') {
        index = 1;
      } else if (!constraint.view2 && constraint.attr2 === 'bottom') {
        index = 2;
      } else {
        switch (constraint.attr1) {
          case 'left':
          case 'right':
          case 'centerX':
          case 'leading':
          case 'trailing':
            index = 4;
            break;
          case 'zIndex':
            index = 6;
            break;
          default:
            index = 5;
        }
      }
      this._spacingVars = this._spacingVars || new Array(7);
      this._spacingExpr = this._spacingExpr || new Array(7);
      if (!this._spacingVars[index]) {
        if (true) {
          this._spacingVars[index] = new c.Variable();
          this._solver.addEditVar(this._spacingVars[index]);
          this._spacingExpr[index] = c.minus(0, this._spacingVars[index]);
        } else {
          this._spacingVars[index] = new kiwi.Variable();
          this._solver.addEditVariable(this._spacingVars[index], kiwi.Strength.create(999, 1000, 1000));
          this._spacingExpr[index] = this._spacingVars[index].multiply(-1);
        }
        this._solver.suggestValue(this._spacingVars[index], this._spacing[index]);
      }
      return this._spacingExpr[index];
    }
    
    function _addConstraint(constraint) {
      //this.constraints.push(constraint);
      var relation = void 0;
      var multiplier = constraint.multiplier !== undefined ? constraint.multiplier : 1;
      var constant = constraint.constant !== undefined ? constraint.constant : 0;
      if (constant === 'default') {
        constant = _getSpacing.call(this, constraint);
      }
      var attr1 = _getSubView.call(this, constraint.view1)._getAttr(constraint.attr1);
      var attr2 = void 0;
      if (true) {
        if (constraint.attr2 === Attribute.CONST) {
          attr2 = _getConst.call(this, undefined, constraint.constant);
        } else {
          attr2 = _getSubView.call(this, constraint.view2)._getAttr(constraint.attr2);
          if (multiplier !== 1 && constant) {
            attr2 = c.plus(c.times(attr2, multiplier), constant);
          } else if (constant) {
            attr2 = c.plus(attr2, constant);
          } else if (multiplier !== 1) {
            attr2 = c.times(attr2, multiplier);
          }
        }
        var strength = constraint.priority !== undefined && constraint.priority < 1000 ? new c.Strength('priority', 0, constraint.priority, 1000) : defaultPriorityStrength;
        switch (constraint.relation) {
          case Relation.EQU:
            relation = new c.Equation(attr1, attr2, strength);
            break;
          case Relation.GEQ:
            relation = new c.Inequality(attr1, c.GEQ, attr2, strength);
            break;
          case Relation.LEQ:
            relation = new c.Inequality(attr1, c.LEQ, attr2, strength);
            break;
          default:
            throw 'Invalid relation specified: ' + constraint.relation;
        }
      } else {
        if (constraint.attr2 === Attribute.CONST) {
          attr2 = _getConst.call(this, undefined, constraint.constant);
        } else {
          attr2 = _getSubView.call(this, constraint.view2)._getAttr(constraint.attr2);
          if (multiplier !== 1 && constant) {
            attr2 = attr2.multiply(multiplier).plus(constant);
          } else if (constant) {
            attr2 = attr2.plus(constant);
          } else if (multiplier !== 1) {
            attr2 = attr2.multiply(multiplier);
          }
        }
        var _strength = constraint.priority !== undefined && constraint.priority < 1000 ? kiwi.Strength.create(0, constraint.priority, 1000) : defaultPriorityStrength;
        switch (constraint.relation) {
          case Relation.EQU:
            relation = new kiwi.Constraint(attr1, kiwi.Operator.Eq, attr2, _strength);
            break;
          case Relation.GEQ:
            relation = new kiwi.Constraint(attr1, kiwi.Operator.Ge, attr2, _strength);
            break;
          case Relation.LEQ:
            relation = new kiwi.Constraint(attr1, kiwi.Operator.Le, attr2, _strength);
            break;
          default:
            throw 'Invalid relation specified: ' + constraint.relation;
        }
      }
      this._solver.addConstraint(relation);
    }
    
    function _compareSpacing(old, newz) {
      if (old === newz) {
        return true;
      }
      if (!old || !newz) {
        return false;
      }
      for (var i = 0; i < 7; i++) {
        if (old[i] !== newz[i]) {
          return false;
        }
      }
      return true;
    }
    
    /**
     * AutoLayoutJS API reference.
     *
     * ### Index
     *
     * |Entity|Type|Description|
     * |---|---|---|
     * |[AutoLayout](#autolayout)|`namespace`|Top level AutoLayout object.|
     * |[VisualFormat](#autolayoutvisualformat--object)|`namespace`|Parses VFL into constraints.|
     * |[View](#autolayoutview)|`class`|Main entity for adding & evaluating constraints.|
     * |[SubView](#autolayoutsubview--object)|`class`|SubView's are automatically created when constraints are added to views. They give access to the evaluated results.|
     * |[Attribute](#autolayoutattribute--enum)|`enum`|Attribute types that are supported when adding constraints.|
     * |[Relation](#autolayoutrelation--enum)|`enum`|Relationship types that are supported when adding constraints.|
     * |[Priority](#autolayoutpriority--enum)|`enum`|Default priority values for when adding constraints.|
     *
     * ### AutoLayout
     *
     * @module AutoLayout
     */
    
    var View = function () {
    
      /**
       * @class View
       * @param {Object} [options] Configuration options.
       * @param {Number} [options.width] Initial width of the view.
       * @param {Number} [options.height] Initial height of the view.
       * @param {Number|Object} [options.spacing] Spacing for the view (default: 8) (see `setSpacing`).
       * @param {Array} [options.constraints] One or more constraint definitions (see `addConstraints`).
       */
      function View(options) {
        _classCallCheck(this, View);
    
        this._solver = true ? new c.SimplexSolver() : new kiwi.Solver();
        this._subViews = {};
        //this._spacing = undefined;
        this._parentSubView = new SubView({
          solver: this._solver
        });
        this.setSpacing(options && options.spacing !== undefined ? options.spacing : 8);
        //this.constraints = [];
        if (options) {
          if (options.width !== undefined || options.height !== undefined) {
            this.setSize(options.width, options.height);
          }
          if (options.constraints) {
            this.addConstraints(options.constraints);
          }
        }
      }
    
      /**
       * Sets the width and height of the view.
       *
       * @param {Number} width Width of the view.
       * @param {Number} height Height of the view.
       * @return {View} this
       */
    
    
      _createClass(View, [{
        key: 'setSize',
        value: function setSize(width, height /*, depth*/) {
          this._parentSubView.intrinsicWidth = width;
          this._parentSubView.intrinsicHeight = height;
          return this;
        }
    
        /**
         * Width that was set using `setSize`.
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'setSpacing',
    
    
        /**
         * Sets the spacing for the view.
         *
         * The spacing can be set for 7 different variables:
         * `top`, `right`, `bottom`, `left`, `width`, `height` and `zIndex`. The `left`-spacing is
         * used when a spacer is used between the parent-view and a sub-view (e.g. `|-[subView]`).
         * The same is true for the `right`, `top` and `bottom` spacers. The `width` and `height` are
         * used for spacers in between sub-views (e.g. `[view1]-[view2]`).
         *
         * Instead of using the full spacing syntax, it is also possible to use shorthand notations:
         *
         * |Syntax|Type|Description|
         * |---|---|---|
         * |`[top, right, bottom, left, width, height, zIndex]`|Array(7)|Full syntax including z-index **(clockwise order)**.|
         * |`[top, right, bottom, left, width, height]`|Array(6)|Full horizontal & vertical spacing syntax (no z-index) **(clockwise order)**.|
         * |`[horizontal, vertical, zIndex]`|Array(3)|Horizontal = left, right, width, vertical = top, bottom, height.|
         * |`[horizontal, vertical]`|Array(2)|Horizontal = left, right, width, vertical = top, bottom, height, z-index = 1.|
         * |`spacing`|Number|Horizontal & vertical spacing are all the same, z-index = 1.|
         *
         * Examples:
         * ```javascript
         * view.setSpacing(10); // horizontal & vertical spacing 10
         * view.setSpacing([10, 15, 2]); // horizontal spacing 10, vertical spacing 15, z-axis spacing 2
         * view.setSpacing([10, 20, 10, 20, 5, 5]); // top, right, bottom, left, horizontal, vertical
         * view.setSpacing([10, 20, 10, 20, 5, 5, 1]); // top, right, bottom, left, horizontal, vertical, z
         * ```
         *
         * @param {Number|Array} spacing
         * @return {View} this
         */
        value: function setSpacing(spacing) {
          // convert spacing into array: [top, right, bottom, left, horz, vert, z-index]
          switch (Array.isArray(spacing) ? spacing.length : -1) {
            case -1:
              spacing = [spacing, spacing, spacing, spacing, spacing, spacing, 1];break;
            case 1:
              spacing = [spacing[0], spacing[0], spacing[0], spacing[0], spacing[0], spacing[0], 1];break;
            case 2:
              spacing = [spacing[1], spacing[0], spacing[1], spacing[0], spacing[0], spacing[1], 1];break;
            case 3:
              spacing = [spacing[1], spacing[0], spacing[1], spacing[0], spacing[0], spacing[1], spacing[2]];break;
            case 6:
              spacing = [spacing[0], spacing[1], spacing[2], spacing[3], spacing[4], spacing[5], 1];break;
            case 7:
              break;
            default:
              throw 'Invalid spacing syntax';
          }
          if (!_compareSpacing(this._spacing, spacing)) {
            this._spacing = spacing;
            // update spacing variables
            if (this._spacingVars) {
              for (var i = 0; i < this._spacingVars.length; i++) {
                if (this._spacingVars[i]) {
                  this._solver.suggestValue(this._spacingVars[i], this._spacing[i]);
                }
              }
              if (true) {
                this._solver.resolve();
              } else {
                this._solver.updateVariables();
              }
            }
          }
          return this;
        }
    
        /**
         * Adds a constraint definition.
         *
         * A constraint definition has the following format:
         *
         * ```javascript
         * constraint: {
         *   view1: {String},
         *   attr1: {AutoLayout.Attribute},
         *   relation: {AutoLayout.Relation},
         *   view2: {String},
         *   attr2: {AutoLayout.Attribute},
         *   multiplier: {Number},
         *   constant: {Number},
         *   priority: {Number}(0..1000)
         * }
         * ```
         * @param {Object} constraint Constraint definition.
         * @return {View} this
         */
    
      }, {
        key: 'addConstraint',
        value: function addConstraint(constraint) {
          _addConstraint.call(this, constraint);
          if (!true) {
            this._solver.updateVariables();
          }
          return this;
        }
    
        /**
         * Adds one or more constraint definitions.
         *
         * A constraint definition has the following format:
         *
         * ```javascript
         * constraint: {
         *   view1: {String},
         *   attr1: {AutoLayout.Attribute},
         *   relation: {AutoLayout.Relation},
         *   view2: {String},
         *   attr2: {AutoLayout.Attribute},
         *   multiplier: {Number},
         *   constant: {Number},
         *   priority: {Number}(0..1000)
         * }
         * ```
         * @param {Array} constraints One or more constraint definitions.
         * @return {View} this
         */
    
      }, {
        key: 'addConstraints',
        value: function addConstraints(constraints) {
          for (var j = 0; j < constraints.length; j++) {
            _addConstraint.call(this, constraints[j]);
          }
          if (!true) {
            this._solver.updateVariables();
          }
          return this;
        }
    
        /**
         * Dictionary of `SubView` objects that have been created when adding constraints.
         * @readonly
         * @type {Object.SubView}
         */
    
      }, {
        key: 'width',
        get: function get() {
          return this._parentSubView.intrinsicWidth;
        }
    
        /**
         * Height that was set using `setSize`.
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'height',
        get: function get() {
          return this._parentSubView.intrinsicHeight;
        }
    
        /**
         * Width that is calculated from the constraints and the `.intrinsicWidth` of
         * the sub-views.
         *
         * When the width has been explicitely set using `setSize`, the fittingWidth
         * will **always** be the same as the explicitely set width. To calculate the size
         * based on the content, use:
         * ```javascript
         * var view = new AutoLayout.View({
         *   constraints: VisualFormat.parse('|-[view1]-[view2]-'),
         *   spacing: 20
         * });
         * view.subViews.view1.intrinsicWidth = 100;
         * view.subViews.view2.intrinsicWidth = 100;
         * console.log('fittingWidth: ' + view.fittingWidth); // 260
         * ```
         *
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'fittingWidth',
        get: function get() {
          return this._parentSubView.width;
        }
    
        /**
         * Height that is calculated from the constraints and the `.intrinsicHeight` of
         * the sub-views.
         *
         * See `.fittingWidth`.
         *
         * @readonly
         * @type {Number}
         */
    
      }, {
        key: 'fittingHeight',
        get: function get() {
          return this._parentSubView.height;
        }
      }, {
        key: 'subViews',
        get: function get() {
          return this._subViews;
        }
    
        /**
         * Checks whether the constraints incompletely specify the location
         * of the subViews.
         * @private
         */
        //get hasAmbiguousLayout() {
        // Todo
        //}
    
      }]);
    
      return View;
    }();
    
    //import DOM from './DOM';
    
    /**
     * AutoLayout.
     *
     * @namespace AutoLayout
     * @property {Attribute} Attribute
     * @property {Relation} Relation
     * @property {Priority} Priority
     * @property {VisualFormat} VisualFormat
     * @property {View} View
     * @property {SubView} SubView
     */
    
    
    var AutoLayout = {
      Attribute: Attribute,
      Relation: Relation,
      Priority: Priority,
      VisualFormat: VisualFormat,
      View: View,
      SubView: SubView
      //DOM: DOM
    };
    
    module.exports = AutoLayout;
    
    },{"cassowary/bin/c":2}],2:[function(require,module,exports){
    /**
     * Parts Copyright (C) 2011-2012, Alex Russell (slightlyoff@chromium.org)
     * Parts Copyright (C) Copyright (C) 1998-2000 Greg J. Badros
     *
     * Use of this source code is governed by the LGPL, which can be found in the
     * COPYING.LGPL file.
     *
     * This is a compiled version of Cassowary/JS. For source versions or to
     * contribute, see the github project:
     *
     *  https://github.com/slightlyoff/cassowary-js-refactor
     *
     */
    
    (function() {
    (function(a){"use strict";try{(function(){}).bind(a)}catch(b){Object.defineProperty(Function.prototype,"bind",{value:function(a){var b=this;return function(){return b.apply(a,arguments)}},enumerable:!1,configurable:!0,writable:!0})}var c=a.HTMLElement!==void 0,d=function(a){for(var b=null;a&&a!=Object.prototype;){if(a.tagName){b=a.tagName;break}a=a.prototype}return b||"div"},e=1e-8,f={},g=function(a,b){if(a&&b){if("function"==typeof a[b])return a[b];var c=a.prototype;if(c&&"function"==typeof c[b])return c[b];if(c!==Object.prototype&&c!==Function.prototype)return"function"==typeof a.__super__?g(a.__super__,b):void 0}},h=a.c={debug:!1,trace:!1,verbose:!1,traceAdded:!1,GC:!1,GEQ:1,LEQ:2,inherit:function(b){var e=null,g=null;b["extends"]&&(g=b["extends"],delete b["extends"]),b.initialize&&(e=b.initialize,delete b.initialize);var h=e||function(){};Object.defineProperty(h,"__super__",{value:g?g:Object,enumerable:!1,configurable:!0,writable:!1}),b._t&&(f[b._t]=h);var i=h.prototype=Object.create(g?g.prototype:Object.prototype);if(this.extend(i,b),c&&g&&g.prototype instanceof a.HTMLElement){var j=h,k=d(i),l=function(a){return a.__proto__=i,j.apply(a,arguments),i.created&&a.created(),i.decorate&&a.decorate(),a};this.extend(i,{upgrade:l}),h=function(){return l(a.document.createElement(k))},h.prototype=i,this.extend(h,{ctor:j})}return h},extend:function(a,b){return this.own(b,function(c){var d=Object.getOwnPropertyDescriptor(b,c);try{"function"==typeof d.get||"function"==typeof d.set?Object.defineProperty(a,c,d):"function"==typeof d.value||"_"===c.charAt(0)?(d.writable=!0,d.configurable=!0,d.enumerable=!1,Object.defineProperty(a,c,d)):a[c]=b[c]}catch(e){}}),a},own:function(b,c,d){return Object.getOwnPropertyNames(b).forEach(c,d||a),b},traceprint:function(a){h.verbose&&console.log(a)},fnenterprint:function(a){console.log("* "+a)},fnexitprint:function(a){console.log("- "+a)},assert:function(a,b){if(!a)throw new h.InternalError("Assertion failed: "+b)},plus:function(a,b){return a instanceof h.Expression||(a=new h.Expression(a)),b instanceof h.Expression||(b=new h.Expression(b)),a.plus(b)},minus:function(a,b){return a instanceof h.Expression||(a=new h.Expression(a)),b instanceof h.Expression||(b=new h.Expression(b)),a.minus(b)},times:function(a,b){return("number"==typeof a||a instanceof h.Variable)&&(a=new h.Expression(a)),("number"==typeof b||b instanceof h.Variable)&&(b=new h.Expression(b)),a.times(b)},divide:function(a,b){return("number"==typeof a||a instanceof h.Variable)&&(a=new h.Expression(a)),("number"==typeof b||b instanceof h.Variable)&&(b=new h.Expression(b)),a.divide(b)},approx:function(a,b){if(a===b)return!0;var c,d;return c=a instanceof h.Variable?a.value:a,d=b instanceof h.Variable?b.value:b,0==c?e>Math.abs(d):0==d?e>Math.abs(c):Math.abs(c-d)<Math.abs(c)*e},_inc:function(a){return function(){return a++}}(0),parseJSON:function(a){return JSON.parse(a,function(a,b){if("object"!=typeof b||"string"!=typeof b._t)return b;var c=b._t,d=f[c];if(c&&d){var e=g(d,"fromJSON");if(e)return e(b,d)}return b})}};"function"==typeof require&&"undefined"!=typeof module&&"undefined"==typeof load&&(a.exports=h)})(this),function(a){"use strict";var b=function(a){var b=a.hashCode?a.hashCode:""+a;return b},c=function(a,b){Object.keys(a).forEach(function(c){b[c]=a[c]})},d={};a.HashTable=a.inherit({initialize:function(){this.size=0,this._store={},this._keyStrMap={},this._deleted=0},set:function(a,c){var d=b(a);this._store.hasOwnProperty(d)||this.size++,this._store[d]=c,this._keyStrMap[d]=a},get:function(a){if(!this.size)return null;a=b(a);var c=this._store[a];return c!==void 0?this._store[a]:null},clear:function(){this.size=0,this._store={},this._keyStrMap={}},_compact:function(){var a={};c(this._store,a),this._store=a},_compactThreshold:100,_perhapsCompact:function(){this._size>64||this._deleted>this._compactThreshold&&(this._compact(),this._deleted=0)},"delete":function(a){a=b(a),this._store.hasOwnProperty(a)&&(this._deleted++,delete this._store[a],this.size>0&&this.size--)},each:function(a,b){if(this.size){this._perhapsCompact();var c=this._store,d=this._keyStrMap;Object.keys(this._store).forEach(function(e){a.call(b||null,d[e],c[e])},this)}},escapingEach:function(a,b){if(this.size){this._perhapsCompact();for(var c=this,e=this._store,f=this._keyStrMap,g=d,h=Object.keys(e),i=0;h.length>i;i++)if(function(d){c._store.hasOwnProperty(d)&&(g=a.call(b||null,f[d],e[d]))}(h[i]),g){if(void 0!==g.retval)return g;if(g.brk)break}}},clone:function(){var b=new a.HashTable;return this.size&&(b.size=this.size,c(this._store,b._store),c(this._keyStrMap,b._keyStrMap)),b},equals:function(b){if(b===this)return!0;if(!(b instanceof a.HashTable)||b._size!==this._size)return!1;for(var c=Object.keys(this._store),d=0;c.length>d;d++){var e=c[d];if(this._keyStrMap[e]!==b._keyStrMap[e]||this._store[e]!==b._store[e])return!1}return!0},toString:function(){var b="";return this.each(function(a,c){b+=a+" => "+c+"\n"}),b}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.HashSet=a.inherit({_t:"c.HashSet",initialize:function(){this.storage=[],this.size=0},add:function(a){var b=this.storage;b.indexOf(a),-1==b.indexOf(a)&&b.push(a),this.size=this.storage.length},values:function(){return this.storage},has:function(a){var b=this.storage;return-1!=b.indexOf(a)},"delete":function(a){var b=this.storage.indexOf(a);return-1==b?null:(this.storage.splice(b,1)[0],this.size=this.storage.length,void 0)},clear:function(){this.storage.length=0},each:function(a,b){this.size&&this.storage.forEach(a,b)},escapingEach:function(a,b){this.size&&this.storage.forEach(a,b)},toString:function(){var a=this.size+" {",b=!0;return this.each(function(c){b?b=!1:a+=", ",a+=c}),a+="}\n"},toJSON:function(){var a=[];return this.each(function(b){a.push(b.toJSON())}),{_t:"c.HashSet",data:a}},fromJSON:function(b){var c=new a.HashSet;return b.data&&(c.size=b.data.length,c.storage=b.data),c}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.Error=a.inherit({initialize:function(a){a&&(this._description=a)},_name:"c.Error",_description:"An error has occured in Cassowary",set description(a){this._description=a},get description(){return"("+this._name+") "+this._description},get message(){return this.description},toString:function(){return this.description}});var b=function(b,c){return a.inherit({"extends":a.Error,initialize:function(){a.Error.apply(this,arguments)},_name:b||"",_description:c||""})};a.ConstraintNotFound=b("c.ConstraintNotFound","Tried to remove a constraint never added to the tableu"),a.InternalError=b("c.InternalError"),a.NonExpression=b("c.NonExpression","The resulting expression would be non"),a.NotEnoughStays=b("c.NotEnoughStays","There are not enough stays to give specific values to every variable"),a.RequiredFailure=b("c.RequiredFailure","A required constraint cannot be satisfied"),a.TooDifficult=b("c.TooDifficult","The constraints are too difficult to solve")}(this.c||module.parent.exports||{}),function(a){"use strict";var b=1e3;a.SymbolicWeight=a.inherit({_t:"c.SymbolicWeight",initialize:function(){this.value=0;for(var a=1,c=arguments.length-1;c>=0;--c)this.value+=arguments[c]*a,a*=b},toJSON:function(){return{_t:this._t,value:this.value}}})}(this.c||module.parent.exports||{}),function(a){a.Strength=a.inherit({initialize:function(b,c,d,e){this.name=b,this.symbolicWeight=c instanceof a.SymbolicWeight?c:new a.SymbolicWeight(c,d,e)},get required(){return this===a.Strength.required},toString:function(){return this.name+(this.isRequired?"":":"+this.symbolicWeight)}}),a.Strength.required=new a.Strength("<Required>",1e3,1e3,1e3),a.Strength.strong=new a.Strength("strong",1,0,0),a.Strength.medium=new a.Strength("medium",0,1,0),a.Strength.weak=new a.Strength("weak",0,0,1)}(this.c||("undefined"!=typeof module?module.parent.exports.c:{})),function(a){"use strict";a.AbstractVariable=a.inherit({isDummy:!1,isExternal:!1,isPivotable:!1,isRestricted:!1,_init:function(b,c){this.hashCode=a._inc(),this.name=(c||"")+this.hashCode,b&&(b.name!==void 0&&(this.name=b.name),b.value!==void 0&&(this.value=b.value),b.prefix!==void 0&&(this._prefix=b.prefix))},_prefix:"",name:"",value:0,toJSON:function(){var a={};return this._t&&(a._t=this._t),this.name&&(a.name=this.name),this.value!==void 0&&(a.value=this.value),this._prefix&&(a._prefix=this._prefix),this._t&&(a._t=this._t),a},fromJSON:function(b,c){var d=new c;return a.extend(d,b),d},toString:function(){return this._prefix+"["+this.name+":"+this.value+"]"}}),a.Variable=a.inherit({_t:"c.Variable","extends":a.AbstractVariable,initialize:function(b){this._init(b,"v");var c=a.Variable._map;c&&(c[this.name]=this)},isExternal:!0}),a.DummyVariable=a.inherit({_t:"c.DummyVariable","extends":a.AbstractVariable,initialize:function(a){this._init(a,"d")},isDummy:!0,isRestricted:!0,value:"dummy"}),a.ObjectiveVariable=a.inherit({_t:"c.ObjectiveVariable","extends":a.AbstractVariable,initialize:function(a){this._init(a,"o")},value:"obj"}),a.SlackVariable=a.inherit({_t:"c.SlackVariable","extends":a.AbstractVariable,initialize:function(a){this._init(a,"s")},isPivotable:!0,isRestricted:!0,value:"slack"})}(this.c||module.parent.exports||{}),function(a){"use strict";a.Point=a.inherit({initialize:function(b,c,d){if(b instanceof a.Variable)this._x=b;else{var e={value:b};d&&(e.name="x"+d),this._x=new a.Variable(e)}if(c instanceof a.Variable)this._y=c;else{var f={value:c};d&&(f.name="y"+d),this._y=new a.Variable(f)}},get x(){return this._x},set x(b){b instanceof a.Variable?this._x=b:this._x.value=b},get y(){return this._y},set y(b){b instanceof a.Variable?this._y=b:this._y.value=b},toString:function(){return"("+this.x+", "+this.y+")"}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.Expression=a.inherit({initialize:function(b,c,d){a.GC&&console.log("new c.Expression"),this.constant="number"!=typeof d||isNaN(d)?0:d,this.terms=new a.HashTable,b instanceof a.AbstractVariable?this.setVariable(b,"number"==typeof c?c:1):"number"==typeof b&&(isNaN(b)?console.trace():this.constant=b)},initializeFromHash:function(b,c){return a.verbose&&(console.log("*******************************"),console.log("clone c.initializeFromHash"),console.log("*******************************")),a.GC&&console.log("clone c.Expression"),this.constant=b,this.terms=c.clone(),this},multiplyMe:function(a){this.constant*=a;var b=this.terms;return b.each(function(c,d){b.set(c,d*a)}),this},clone:function(){a.verbose&&(console.log("*******************************"),console.log("clone c.Expression"),console.log("*******************************"));var b=new a.Expression;return b.initializeFromHash(this.constant,this.terms),b},times:function(b){if("number"==typeof b)return this.clone().multiplyMe(b);if(this.isConstant)return b.times(this.constant);if(b.isConstant)return this.times(b.constant);throw new a.NonExpression},plus:function(b){return b instanceof a.Expression?this.clone().addExpression(b,1):b instanceof a.Variable?this.clone().addVariable(b,1):void 0},minus:function(b){return b instanceof a.Expression?this.clone().addExpression(b,-1):b instanceof a.Variable?this.clone().addVariable(b,-1):void 0},divide:function(b){if("number"==typeof b){if(a.approx(b,0))throw new a.NonExpression;return this.times(1/b)}if(b instanceof a.Expression){if(!b.isConstant)throw new a.NonExpression;return this.times(1/b.constant)}},addExpression:function(b,c,d,e){return b instanceof a.AbstractVariable&&(b=new a.Expression(b),a.trace&&console.log("addExpression: Had to cast a var to an expression")),c=c||1,this.constant+=c*b.constant,b.terms.each(function(a,b){this.addVariable(a,b*c,d,e)},this),this},addVariable:function(b,c,d,e){null==c&&(c=1),a.trace&&console.log("c.Expression::addVariable():",b,c);var f=this.terms.get(b);if(f){var g=f+c;0==g||a.approx(g,0)?(e&&e.noteRemovedVariable(b,d),this.terms.delete(b)):this.setVariable(b,g)}else a.approx(c,0)||(this.setVariable(b,c),e&&e.noteAddedVariable(b,d));return this},setVariable:function(a,b){return this.terms.set(a,b),this},anyPivotableVariable:function(){if(this.isConstant)throw new a.InternalError("anyPivotableVariable called on a constant");var b=this.terms.escapingEach(function(a){return a.isPivotable?{retval:a}:void 0});return b&&void 0!==b.retval?b.retval:null},substituteOut:function(b,c,d,e){a.trace&&(a.fnenterprint("CLE:substituteOut: "+b+", "+c+", "+d+", ..."),a.traceprint("this = "+this));var f=this.setVariable.bind(this),g=this.terms,h=g.get(b);g.delete(b),this.constant+=h*c.constant,c.terms.each(function(b,c){var i=g.get(b);if(i){var j=i+h*c;a.approx(j,0)?(e.noteRemovedVariable(b,d),g.delete(b)):f(b,j)}else f(b,h*c),e&&e.noteAddedVariable(b,d)}),a.trace&&a.traceprint("Now this is "+this)},changeSubject:function(a,b){this.setVariable(a,this.newSubject(b))},newSubject:function(b){a.trace&&a.fnenterprint("newSubject:"+b);var c=1/this.terms.get(b);return this.terms.delete(b),this.multiplyMe(-c),c},coefficientFor:function(a){return this.terms.get(a)||0},get isConstant(){return 0==this.terms.size},toString:function(){var b="",c=!1;if(!a.approx(this.constant,0)||this.isConstant){if(b+=this.constant,this.isConstant)return b;c=!0}return this.terms.each(function(a,d){c&&(b+=" + "),b+=d+"*"+a,c=!0}),b},equals:function(b){return b===this?!0:b instanceof a.Expression&&b.constant===this.constant&&b.terms.equals(this.terms)},Plus:function(a,b){return a.plus(b)},Minus:function(a,b){return a.minus(b)},Times:function(a,b){return a.times(b)},Divide:function(a,b){return a.divide(b)}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.AbstractConstraint=a.inherit({initialize:function(b,c){this.hashCode=a._inc(),this.strength=b||a.Strength.required,this.weight=c||1},isEditConstraint:!1,isInequality:!1,isStayConstraint:!1,get required(){return this.strength===a.Strength.required},toString:function(){return this.strength+" {"+this.weight+"} ("+this.expression+")"}});var b=a.AbstractConstraint.prototype.toString,c=function(b,c,d){a.AbstractConstraint.call(this,c||a.Strength.strong,d),this.variable=b,this.expression=new a.Expression(b,-1,b.value)};a.EditConstraint=a.inherit({"extends":a.AbstractConstraint,initialize:function(){c.apply(this,arguments)},isEditConstraint:!0,toString:function(){return"edit:"+b.call(this)}}),a.StayConstraint=a.inherit({"extends":a.AbstractConstraint,initialize:function(){c.apply(this,arguments)},isStayConstraint:!0,toString:function(){return"stay:"+b.call(this)}});var d=a.Constraint=a.inherit({"extends":a.AbstractConstraint,initialize:function(b,c,d){a.AbstractConstraint.call(this,c,d),this.expression=b}});a.Inequality=a.inherit({"extends":a.Constraint,_cloneOrNewCle:function(b){return b.clone?b.clone():new a.Expression(b)},initialize:function(b,c,e,f,g){var h=b instanceof a.Expression,i=e instanceof a.Expression,j=b instanceof a.AbstractVariable,k=e instanceof a.AbstractVariable,l="number"==typeof b,m="number"==typeof e;if((h||l)&&k){var n=b,o=c,p=e,q=f,r=g;if(d.call(this,this._cloneOrNewCle(n),q,r),o==a.LEQ)this.expression.multiplyMe(-1),this.expression.addVariable(p);else{if(o!=a.GEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");this.expression.addVariable(p,-1)}}else if(j&&(i||m)){var n=e,o=c,p=b,q=f,r=g;if(d.call(this,this._cloneOrNewCle(n),q,r),o==a.GEQ)this.expression.multiplyMe(-1),this.expression.addVariable(p);else{if(o!=a.LEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");this.expression.addVariable(p,-1)}}else{if(h&&m){var s=b,o=c,t=e,q=f,r=g;if(d.call(this,this._cloneOrNewCle(s),q,r),o==a.LEQ)this.expression.multiplyMe(-1),this.expression.addExpression(this._cloneOrNewCle(t));else{if(o!=a.GEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");this.expression.addExpression(this._cloneOrNewCle(t),-1)}return this}if(l&&i){var s=e,o=c,t=b,q=f,r=g;if(d.call(this,this._cloneOrNewCle(s),q,r),o==a.GEQ)this.expression.multiplyMe(-1),this.expression.addExpression(this._cloneOrNewCle(t));else{if(o!=a.LEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");this.expression.addExpression(this._cloneOrNewCle(t),-1)}return this}if(h&&i){var s=b,o=c,t=e,q=f,r=g;if(d.call(this,this._cloneOrNewCle(t),q,r),o==a.GEQ)this.expression.multiplyMe(-1),this.expression.addExpression(this._cloneOrNewCle(s));else{if(o!=a.LEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");this.expression.addExpression(this._cloneOrNewCle(s),-1)}}else{if(h)return d.call(this,b,c,e);if(c==a.GEQ)d.call(this,new a.Expression(e),f,g),this.expression.multiplyMe(-1),this.expression.addVariable(b);else{if(c!=a.LEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");d.call(this,new a.Expression(e),f,g),this.expression.addVariable(b,-1)}}}},isInequality:!0,toString:function(){return d.prototype.toString.call(this)+" >= 0) id: "+this.hashCode}}),a.Equation=a.inherit({"extends":a.Constraint,initialize:function(b,c,e,f){if(b instanceof a.Expression&&!c||c instanceof a.Strength)d.call(this,b,c,e);else if(b instanceof a.AbstractVariable&&c instanceof a.Expression){var g=b,h=c,i=e,j=f;d.call(this,h.clone(),i,j),this.expression.addVariable(g,-1)}else if(b instanceof a.AbstractVariable&&"number"==typeof c){var g=b,k=c,i=e,j=f;d.call(this,new a.Expression(k),i,j),this.expression.addVariable(g,-1)}else if(b instanceof a.Expression&&c instanceof a.AbstractVariable){var h=b,g=c,i=e,j=f;d.call(this,h.clone(),i,j),this.expression.addVariable(g,-1)}else{if(!(b instanceof a.Expression||b instanceof a.AbstractVariable||"number"==typeof b)||!(c instanceof a.Expression||c instanceof a.AbstractVariable||"number"==typeof c))throw"Bad initializer to c.Equation";b=b instanceof a.Expression?b.clone():new a.Expression(b),c=c instanceof a.Expression?c.clone():new a.Expression(c),d.call(this,b,e,f),this.expression.addExpression(c,-1)}a.assert(this.strength instanceof a.Strength,"_strength not set")},toString:function(){return d.prototype.toString.call(this)+" = 0)"}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.EditInfo=a.inherit({initialize:function(a,b,c,d,e){this.constraint=a,this.editPlus=b,this.editMinus=c,this.prevEditConstant=d,this.index=e},toString:function(){return"<cn="+this.constraint+", ep="+this.editPlus+", em="+this.editMinus+", pec="+this.prevEditConstant+", index="+this.index+">"}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.Tableau=a.inherit({initialize:function(){this.columns=new a.HashTable,this.rows=new a.HashTable,this._infeasibleRows=new a.HashSet,this._externalRows=new a.HashSet,this._externalParametricVars=new a.HashSet},noteRemovedVariable:function(b,c){a.trace&&console.log("c.Tableau::noteRemovedVariable: ",b,c);var d=this.columns.get(b);c&&d&&d.delete(c)},noteAddedVariable:function(a,b){b&&this.insertColVar(a,b)},getInternalInfo:function(){var a="Tableau Information:\n";return a+="Rows: "+this.rows.size,a+=" (= "+(this.rows.size-1)+" constraints)",a+="\nColumns: "+this.columns.size,a+="\nInfeasible Rows: "+this._infeasibleRows.size,a+="\nExternal basic variables: "+this._externalRows.size,a+="\nExternal parametric variables: ",a+=this._externalParametricVars.size,a+="\n"},toString:function(){var a="Tableau:\n";return this.rows.each(function(b,c){a+=b,a+=" <==> ",a+=c,a+="\n"}),a+="\nColumns:\n",a+=this.columns,a+="\nInfeasible rows: ",a+=this._infeasibleRows,a+="External basic variables: ",a+=this._externalRows,a+="External parametric variables: ",a+=this._externalParametricVars},insertColVar:function(b,c){var d=this.columns.get(b);d||(d=new a.HashSet,this.columns.set(b,d)),d.add(c)},addRow:function(b,c){a.trace&&a.fnenterprint("addRow: "+b+", "+c),this.rows.set(b,c),c.terms.each(function(a){this.insertColVar(a,b),a.isExternal&&this._externalParametricVars.add(a)},this),b.isExternal&&this._externalRows.add(b),a.trace&&a.traceprint(""+this)},removeColumn:function(b){a.trace&&a.fnenterprint("removeColumn:"+b);var c=this.columns.get(b);c?(this.columns.delete(b),c.each(function(a){var c=this.rows.get(a);c.terms.delete(b)},this)):a.trace&&console.log("Could not find var",b,"in columns"),b.isExternal&&(this._externalRows.delete(b),this._externalParametricVars.delete(b))},removeRow:function(b){a.trace&&a.fnenterprint("removeRow:"+b);var c=this.rows.get(b);return a.assert(null!=c),c.terms.each(function(c){var e=this.columns.get(c);null!=e&&(a.trace&&console.log("removing from varset:",b),e.delete(b))},this),this._infeasibleRows.delete(b),b.isExternal&&this._externalRows.delete(b),this.rows.delete(b),a.trace&&a.fnexitprint("returning "+c),c},substituteOut:function(b,c){a.trace&&a.fnenterprint("substituteOut:"+b+", "+c),a.trace&&a.traceprint(""+this);var d=this.columns.get(b);d.each(function(a){var d=this.rows.get(a);d.substituteOut(b,c,a,this),a.isRestricted&&0>d.constant&&this._infeasibleRows.add(a)},this),b.isExternal&&(this._externalRows.add(b),this._externalParametricVars.delete(b)),this.columns.delete(b)},columnsHasKey:function(a){return!!this.columns.get(a)}})}(this.c||module.parent.exports||{}),function(a){var b=a.Tableau,c=b.prototype,d=1e-8,e=a.Strength.weak;a.SimplexSolver=a.inherit({"extends":a.Tableau,initialize:function(){a.Tableau.call(this),this._stayMinusErrorVars=[],this._stayPlusErrorVars=[],this._errorVars=new a.HashTable,this._markerVars=new a.HashTable,this._objective=new a.ObjectiveVariable({name:"Z"}),this._editVarMap=new a.HashTable,this._editVarList=[],this._slackCounter=0,this._artificialCounter=0,this._dummyCounter=0,this.autoSolve=!0,this._fNeedsSolving=!1,this._optimizeCount=0,this.rows.set(this._objective,new a.Expression),this._stkCedcns=[0],a.trace&&a.traceprint("objective expr == "+this.rows.get(this._objective))},addLowerBound:function(b,c){var d=new a.Inequality(b,a.GEQ,new a.Expression(c));return this.addConstraint(d)},addUpperBound:function(b,c){var d=new a.Inequality(b,a.LEQ,new a.Expression(c));return this.addConstraint(d)},addBounds:function(a,b,c){return this.addLowerBound(a,b),this.addUpperBound(a,c),this},add:function(){for(var a=0;arguments.length>a;a++)this.addConstraint(arguments[a]);return this},addConstraint:function(b){a.trace&&a.fnenterprint("addConstraint: "+b);var c=Array(2),d=Array(1),e=this.newExpression(b,c,d);if(d=d[0],this.tryAddingDirectly(e)||this.addWithArtificialVariable(e),this._fNeedsSolving=!0,b.isEditConstraint){var f=this._editVarMap.size,g=c[0],h=c[1];!g instanceof a.SlackVariable&&console.warn("cvEplus not a slack variable =",g),!h instanceof a.SlackVariable&&console.warn("cvEminus not a slack variable =",h),a.debug&&console.log("new c.EditInfo("+b+", "+g+", "+h+", "+d+", "+f+")");var i=new a.EditInfo(b,g,h,d,f);this._editVarMap.set(b.variable,i),this._editVarList[f]={v:b.variable,info:i}}return this.autoSolve&&(this.optimize(this._objective),this._setExternalVariables()),this},addConstraintNoException:function(b){a.trace&&a.fnenterprint("addConstraintNoException: "+b);try{return this.addConstraint(b),!0}catch(c){return!1}},addEditVar:function(b,c){return a.trace&&a.fnenterprint("addEditVar: "+b+" @ "+c),this.addConstraint(new a.EditConstraint(b,c||a.Strength.strong))},beginEdit:function(){return a.assert(this._editVarMap.size>0,"_editVarMap.size > 0"),this._infeasibleRows.clear(),this._resetStayConstants(),this._stkCedcns.push(this._editVarMap.size),this},endEdit:function(){return a.assert(this._editVarMap.size>0,"_editVarMap.size > 0"),this.resolve(),this._stkCedcns.pop(),this.removeEditVarsTo(this._stkCedcns[this._stkCedcns.length-1]),this},removeAllEditVars:function(){return this.removeEditVarsTo(0)},removeEditVarsTo:function(b){try{for(var c=this._editVarList.length,d=b;c>d;d++)this._editVarList[d]&&this.removeConstraint(this._editVarMap.get(this._editVarList[d].v).constraint);return this._editVarList.length=b,a.assert(this._editVarMap.size==b,"_editVarMap.size == n"),this}catch(e){throw new a.InternalError("Constraint not found in removeEditVarsTo")}},addPointStays:function(b){return a.trace&&console.log("addPointStays",b),b.forEach(function(a,b){this.addStay(a.x,e,Math.pow(2,b)),this.addStay(a.y,e,Math.pow(2,b))},this),this},addStay:function(b,c,d){var f=new a.StayConstraint(b,c||e,d||1);return this.addConstraint(f)},removeConstraint:function(a){return this.removeConstraintInternal(a),this},removeConstraintInternal:function(b){a.trace&&a.fnenterprint("removeConstraintInternal: "+b),a.trace&&a.traceprint(""+this),this._fNeedsSolving=!0,this._resetStayConstants();var c=this.rows.get(this._objective),d=this._errorVars.get(b);a.trace&&a.traceprint("eVars == "+d),null!=d&&d.each(function(e){var f=this.rows.get(e);null==f?c.addVariable(e,-b.weight*b.strength.symbolicWeight.value,this._objective,this):c.addExpression(f,-b.weight*b.strength.symbolicWeight.value,this._objective,this),a.trace&&a.traceprint("now eVars == "+d)},this);var e=this._markerVars.get(b);if(this._markerVars.delete(b),null==e)throw new a.InternalError("Constraint not found in removeConstraintInternal");if(a.trace&&a.traceprint("Looking to remove var "+e),null==this.rows.get(e)){var f=this.columns.get(e);a.trace&&a.traceprint("Must pivot -- columns are "+f);var g=null,h=0;f.each(function(b){if(b.isRestricted){var c=this.rows.get(b),d=c.coefficientFor(e);if(a.trace&&a.traceprint("Marker "+e+"'s coefficient in "+c+" is "+d),0>d){var f=-c.constant/d;(null==g||h>f||a.approx(f,h)&&b.hashCode<g.hashCode)&&(h=f,g=b)}}},this),null==g&&(a.trace&&a.traceprint("exitVar is still null"),f.each(function(a){if(a.isRestricted){var b=this.rows.get(a),c=b.coefficientFor(e),d=b.constant/c;(null==g||h>d)&&(h=d,g=a)}},this)),null==g&&(0==f.size?this.removeColumn(e):f.escapingEach(function(a){return a!=this._objective?(g=a,{brk:!0}):void 0},this)),null!=g&&this.pivot(e,g)}if(null!=this.rows.get(e)&&this.removeRow(e),null!=d&&d.each(function(a){a!=e&&this.removeColumn(a)},this),b.isStayConstraint){if(null!=d)for(var j=0;this._stayPlusErrorVars.length>j;j++)d.delete(this._stayPlusErrorVars[j]),d.delete(this._stayMinusErrorVars[j])}else if(b.isEditConstraint){a.assert(null!=d,"eVars != null");var k=this._editVarMap.get(b.variable);this.removeColumn(k.editMinus),this._editVarMap.delete(b.variable)}return null!=d&&this._errorVars.delete(d),this.autoSolve&&(this.optimize(this._objective),this._setExternalVariables()),this},reset:function(){throw a.trace&&a.fnenterprint("reset"),new a.InternalError("reset not implemented")},resolveArray:function(b){a.trace&&a.fnenterprint("resolveArray"+b);var c=b.length;this._editVarMap.each(function(a,d){var e=d.index;c>e&&this.suggestValue(a,b[e])},this),this.resolve()},resolvePair:function(a,b){this.suggestValue(this._editVarList[0].v,a),this.suggestValue(this._editVarList[1].v,b),this.resolve()},resolve:function(){a.trace&&a.fnenterprint("resolve()"),this.dualOptimize(),this._setExternalVariables(),this._infeasibleRows.clear(),this._resetStayConstants()},suggestValue:function(b,c){a.trace&&console.log("suggestValue("+b+", "+c+")");var d=this._editVarMap.get(b);if(!d)throw new a.Error("suggestValue for variable "+b+", but var is not an edit variable");var e=c-d.prevEditConstant;return d.prevEditConstant=c,this.deltaEditConstant(e,d.editPlus,d.editMinus),this},solve:function(){return this._fNeedsSolving&&(this.optimize(this._objective),this._setExternalVariables()),this},setEditedValue:function(b,c){if(!this.columnsHasKey(b)&&null==this.rows.get(b))return b.value=c,this;if(!a.approx(c,b.value)){this.addEditVar(b),this.beginEdit();try{this.suggestValue(b,c)}catch(d){throw new a.InternalError("Error in setEditedValue")}this.endEdit()}return this},addVar:function(b){if(!this.columnsHasKey(b)&&null==this.rows.get(b)){try{this.addStay(b)}catch(c){throw new a.InternalError("Error in addVar -- required failure is impossible")}a.trace&&a.traceprint("added initial stay on "+b)}return this},getInternalInfo:function(){var a=c.getInternalInfo.call(this);return a+="\nSolver info:\n",a+="Stay Error Variables: ",a+=this._stayPlusErrorVars.length+this._stayMinusErrorVars.length,a+=" ("+this._stayPlusErrorVars.length+" +, ",a+=this._stayMinusErrorVars.length+" -)\n",a+="Edit Variables: "+this._editVarMap.size,a+="\n"},getDebugInfo:function(){return""+this+this.getInternalInfo()+"\n"},toString:function(){var a=c.getInternalInfo.call(this);return a+="\n_stayPlusErrorVars: ",a+="["+this._stayPlusErrorVars+"]",a+="\n_stayMinusErrorVars: ",a+="["+this._stayMinusErrorVars+"]",a+="\n",a+="_editVarMap:\n"+this._editVarMap,a+="\n"},getConstraintMap:function(){return this._markerVars},addWithArtificialVariable:function(b){a.trace&&a.fnenterprint("addWithArtificialVariable: "+b);var c=new a.SlackVariable({value:++this._artificialCounter,prefix:"a"}),d=new a.ObjectiveVariable({name:"az"}),e=b.clone();a.trace&&a.traceprint("before addRows:\n"+this),this.addRow(d,e),this.addRow(c,b),a.trace&&a.traceprint("after addRows:\n"+this),this.optimize(d);var f=this.rows.get(d);if(a.trace&&a.traceprint("azTableauRow.constant == "+f.constant),!a.approx(f.constant,0))throw this.removeRow(d),this.removeColumn(c),new a.RequiredFailure;var g=this.rows.get(c);if(null!=g){if(g.isConstant)return this.removeRow(c),this.removeRow(d),void 0;var h=g.anyPivotableVariable();this.pivot(h,c)}a.assert(null==this.rows.get(c),"rowExpression(av) == null"),this.removeColumn(c),this.removeRow(d)},tryAddingDirectly:function(b){a.trace&&a.fnenterprint("tryAddingDirectly: "+b);var c=this.chooseSubject(b);return null==c?(a.trace&&a.fnexitprint("returning false"),!1):(b.newSubject(c),this.columnsHasKey(c)&&this.substituteOut(c,b),this.addRow(c,b),a.trace&&a.fnexitprint("returning true"),!0)},chooseSubject:function(b){a.trace&&a.fnenterprint("chooseSubject: "+b);var c=null,d=!1,e=!1,f=b.terms,g=f.escapingEach(function(a,b){if(d){if(!a.isRestricted&&!this.columnsHasKey(a))return{retval:a}}else if(a.isRestricted){if(!e&&!a.isDummy&&0>b){var f=this.columns.get(a);(null==f||1==f.size&&this.columnsHasKey(this._objective))&&(c=a,e=!0)}}else c=a,d=!0},this);if(g&&void 0!==g.retval)return g.retval;if(null!=c)return c;var h=0,g=f.escapingEach(function(a,b){return a.isDummy?(this.columnsHasKey(a)||(c=a,h=b),void 0):{retval:null}},this);if(g&&void 0!==g.retval)return g.retval;if(!a.approx(b.constant,0))throw new a.RequiredFailure;return h>0&&b.multiplyMe(-1),c},deltaEditConstant:function(b,c,d){a.trace&&a.fnenterprint("deltaEditConstant :"+b+", "+c+", "+d);var e=this.rows.get(c);if(null!=e)return e.constant+=b,0>e.constant&&this._infeasibleRows.add(c),void 0;var f=this.rows.get(d);if(null!=f)return f.constant+=-b,0>f.constant&&this._infeasibleRows.add(d),void 0;var g=this.columns.get(d);g||console.log("columnVars is null -- tableau is:\n"+this),g.each(function(a){var c=this.rows.get(a),e=c.coefficientFor(d);c.constant+=e*b,a.isRestricted&&0>c.constant&&this._infeasibleRows.add(a)},this)},dualOptimize:function(){a.trace&&a.fnenterprint("dualOptimize:");for(var b=this.rows.get(this._objective);this._infeasibleRows.size;){var c=this._infeasibleRows.values()[0];this._infeasibleRows.delete(c);var d=null,e=this.rows.get(c);if(e&&0>e.constant){var g,f=Number.MAX_VALUE,h=e.terms;if(h.each(function(c,e){if(e>0&&c.isPivotable){var h=b.coefficientFor(c);g=h/e,(f>g||a.approx(g,f)&&c.hashCode<d.hashCode)&&(d=c,f=g)}}),f==Number.MAX_VALUE)throw new a.InternalError("ratio == nil (MAX_VALUE) in dualOptimize");this.pivot(d,c)}}},newExpression:function(b,c,d){a.trace&&(a.fnenterprint("newExpression: "+b),a.traceprint("cn.isInequality == "+b.isInequality),a.traceprint("cn.required == "+b.required));var e=b.expression,f=new a.Expression(e.constant),g=new a.SlackVariable,h=new a.DummyVariable,i=new a.SlackVariable,j=new a.SlackVariable,k=e.terms;if(k.each(function(a,b){var c=this.rows.get(a);c?f.addExpression(c,b):f.addVariable(a,b)},this),b.isInequality){if(a.trace&&a.traceprint("Inequality, adding slack"),++this._slackCounter,g=new a.SlackVariable({value:this._slackCounter,prefix:"s"}),f.setVariable(g,-1),this._markerVars.set(b,g),!b.required){++this._slackCounter,i=new a.SlackVariable({value:this._slackCounter,prefix:"em"}),f.setVariable(i,1);
    var l=this.rows.get(this._objective);l.setVariable(i,b.strength.symbolicWeight.value*b.weight),this.insertErrorVar(b,i),this.noteAddedVariable(i,this._objective)}}else if(b.required)a.trace&&a.traceprint("Equality, required"),++this._dummyCounter,h=new a.DummyVariable({value:this._dummyCounter,prefix:"d"}),f.setVariable(h,1),this._markerVars.set(b,h),a.trace&&a.traceprint("Adding dummyVar == d"+this._dummyCounter);else{a.trace&&a.traceprint("Equality, not required"),++this._slackCounter,j=new a.SlackVariable({value:this._slackCounter,prefix:"ep"}),i=new a.SlackVariable({value:this._slackCounter,prefix:"em"}),f.setVariable(j,-1),f.setVariable(i,1),this._markerVars.set(b,j);var l=this.rows.get(this._objective);a.trace&&console.log(l);var m=b.strength.symbolicWeight.value*b.weight;0==m&&(a.trace&&a.traceprint("cn == "+b),a.trace&&a.traceprint("adding "+j+" and "+i+" with swCoeff == "+m)),l.setVariable(j,m),this.noteAddedVariable(j,this._objective),l.setVariable(i,m),this.noteAddedVariable(i,this._objective),this.insertErrorVar(b,i),this.insertErrorVar(b,j),b.isStayConstraint?(this._stayPlusErrorVars.push(j),this._stayMinusErrorVars.push(i)):b.isEditConstraint&&(c[0]=j,c[1]=i,d[0]=e.constant)}return 0>f.constant&&f.multiplyMe(-1),a.trace&&a.fnexitprint("returning "+f),f},optimize:function(b){a.trace&&a.fnenterprint("optimize: "+b),a.trace&&a.traceprint(""+this),this._optimizeCount++;var c=this.rows.get(b);a.assert(null!=c,"zRow != null");for(var g,h,e=null,f=null;;){if(g=0,h=c.terms,h.escapingEach(function(a,b){return a.isPivotable&&g>b?(g=b,e=a,{brk:1}):void 0},this),g>=-d)return;a.trace&&console.log("entryVar:",e,"objectiveCoeff:",g);var i=Number.MAX_VALUE,j=this.columns.get(e),k=0;if(j.each(function(b){if(a.trace&&a.traceprint("Checking "+b),b.isPivotable){var c=this.rows.get(b),d=c.coefficientFor(e);a.trace&&a.traceprint("pivotable, coeff = "+d),0>d&&(k=-c.constant/d,(i>k||a.approx(k,i)&&b.hashCode<f.hashCode)&&(i=k,f=b))}},this),i==Number.MAX_VALUE)throw new a.InternalError("Objective function is unbounded in optimize");this.pivot(e,f),a.trace&&a.traceprint(""+this)}},pivot:function(b,c){a.trace&&console.log("pivot: ",b,c);var d=!1;d&&console.time(" SimplexSolver::pivot"),null==b&&console.warn("pivot: entryVar == null"),null==c&&console.warn("pivot: exitVar == null"),d&&console.time("  removeRow");var e=this.removeRow(c);d&&console.timeEnd("  removeRow"),d&&console.time("  changeSubject"),e.changeSubject(c,b),d&&console.timeEnd("  changeSubject"),d&&console.time("  substituteOut"),this.substituteOut(b,e),d&&console.timeEnd("  substituteOut"),d&&console.time("  addRow"),this.addRow(b,e),d&&console.timeEnd("  addRow"),d&&console.timeEnd(" SimplexSolver::pivot")},_resetStayConstants:function(){a.trace&&console.log("_resetStayConstants");for(var b=0;this._stayPlusErrorVars.length>b;b++){var c=this.rows.get(this._stayPlusErrorVars[b]);null==c&&(c=this.rows.get(this._stayMinusErrorVars[b])),null!=c&&(c.constant=0)}},_setExternalVariables:function(){a.trace&&a.fnenterprint("_setExternalVariables:"),a.trace&&a.traceprint(""+this),this._externalParametricVars.each(function(b){null!=this.rows.get(b)?a.trace&&console.log("Error: variable"+b+" in _externalParametricVars is basic"):b.value=0},this),this._externalRows.each(function(a){var b=this.rows.get(a);a.value!=b.constant&&(a.value=b.constant)},this),this._fNeedsSolving=!1,this.onsolved()},onsolved:function(){},insertErrorVar:function(b,c){a.trace&&a.fnenterprint("insertErrorVar:"+b+", "+c);var d=this._errorVars.get(c);d||(d=new a.HashSet,this._errorVars.set(b,d)),d.add(c)}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.Timer=a.inherit({initialize:function(){this.isRunning=!1,this._elapsedMs=0},start:function(){return this.isRunning=!0,this._startReading=new Date,this},stop:function(){return this.isRunning=!1,this._elapsedMs+=new Date-this._startReading,this},reset:function(){return this.isRunning=!1,this._elapsedMs=0,this},elapsedTime:function(){return this.isRunning?(this._elapsedMs+(new Date-this._startReading))/1e3:this._elapsedMs/1e3}})}(this.c||module.parent.exports||{}),__cassowary_parser=function(){function a(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\x08/g,"\\b").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g,escape)+'"'}var b={parse:function(b,c){function k(a){g>e||(e>g&&(g=e,h=[]),h.push(a))}function l(){var a,b,c,d,f;if(d=e,f=e,a=z(),null!==a){if(c=m(),null!==c)for(b=[];null!==c;)b.push(c),c=m();else b=null;null!==b?(c=z(),null!==c?a=[a,b,c]:(a=null,e=f)):(a=null,e=f)}else a=null,e=f;return null!==a&&(a=function(a,b){return b}(d,a[1])),null===a&&(e=d),a}function m(){var a,b,c,d;return c=e,d=e,a=P(),null!==a?(b=s(),null!==b?a=[a,b]:(a=null,e=d)):(a=null,e=d),null!==a&&(a=function(a,b){return b}(c,a[0])),null===a&&(e=c),a}function n(){var a;return b.length>e?(a=b.charAt(e),e++):(a=null,0===f&&k("any character")),a}function o(){var a;return/^[a-zA-Z]/.test(b.charAt(e))?(a=b.charAt(e),e++):(a=null,0===f&&k("[a-zA-Z]")),null===a&&(36===b.charCodeAt(e)?(a="$",e++):(a=null,0===f&&k('"$"')),null===a&&(95===b.charCodeAt(e)?(a="_",e++):(a=null,0===f&&k('"_"')))),a}function p(){var a;return f++,/^[\t\x0B\f \xA0\uFEFF]/.test(b.charAt(e))?(a=b.charAt(e),e++):(a=null,0===f&&k("[\\t\\x0B\\f \\xA0\\uFEFF]")),f--,0===f&&null===a&&k("whitespace"),a}function q(){var a;return/^[\n\r\u2028\u2029]/.test(b.charAt(e))?(a=b.charAt(e),e++):(a=null,0===f&&k("[\\n\\r\\u2028\\u2029]")),a}function r(){var a;return f++,10===b.charCodeAt(e)?(a="\n",e++):(a=null,0===f&&k('"\\n"')),null===a&&("\r\n"===b.substr(e,2)?(a="\r\n",e+=2):(a=null,0===f&&k('"\\r\\n"')),null===a&&(13===b.charCodeAt(e)?(a="\r",e++):(a=null,0===f&&k('"\\r"')),null===a&&(8232===b.charCodeAt(e)?(a="\u2028",e++):(a=null,0===f&&k('"\\u2028"')),null===a&&(8233===b.charCodeAt(e)?(a="\u2029",e++):(a=null,0===f&&k('"\\u2029"')))))),f--,0===f&&null===a&&k("end of line"),a}function s(){var a,c,d;return d=e,a=z(),null!==a?(59===b.charCodeAt(e)?(c=";",e++):(c=null,0===f&&k('";"')),null!==c?a=[a,c]:(a=null,e=d)):(a=null,e=d),null===a&&(d=e,a=y(),null!==a?(c=r(),null!==c?a=[a,c]:(a=null,e=d)):(a=null,e=d),null===a&&(d=e,a=z(),null!==a?(c=t(),null!==c?a=[a,c]:(a=null,e=d)):(a=null,e=d))),a}function t(){var a,c;return c=e,f++,b.length>e?(a=b.charAt(e),e++):(a=null,0===f&&k("any character")),f--,null===a?a="":(a=null,e=c),a}function u(){var a;return f++,a=v(),null===a&&(a=x()),f--,0===f&&null===a&&k("comment"),a}function v(){var a,c,d,g,h,i,j;if(h=e,"/*"===b.substr(e,2)?(a="/*",e+=2):(a=null,0===f&&k('"/*"')),null!==a){for(c=[],i=e,j=e,f++,"*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==d;)c.push(d),i=e,j=e,f++,"*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==c?("*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),null!==d?a=[a,c,d]:(a=null,e=h)):(a=null,e=h)}else a=null,e=h;return a}function w(){var a,c,d,g,h,i,j;if(h=e,"/*"===b.substr(e,2)?(a="/*",e+=2):(a=null,0===f&&k('"/*"')),null!==a){for(c=[],i=e,j=e,f++,"*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),null===d&&(d=q()),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==d;)c.push(d),i=e,j=e,f++,"*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),null===d&&(d=q()),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==c?("*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),null!==d?a=[a,c,d]:(a=null,e=h)):(a=null,e=h)}else a=null,e=h;return a}function x(){var a,c,d,g,h,i,j;if(h=e,"//"===b.substr(e,2)?(a="//",e+=2):(a=null,0===f&&k('"//"')),null!==a){for(c=[],i=e,j=e,f++,d=q(),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==d;)c.push(d),i=e,j=e,f++,d=q(),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==c?a=[a,c]:(a=null,e=h)}else a=null,e=h;return a}function y(){var a,b;for(a=[],b=p(),null===b&&(b=w(),null===b&&(b=x()));null!==b;)a.push(b),b=p(),null===b&&(b=w(),null===b&&(b=x()));return a}function z(){var a,b;for(a=[],b=p(),null===b&&(b=r(),null===b&&(b=u()));null!==b;)a.push(b),b=p(),null===b&&(b=r(),null===b&&(b=u()));return a}function A(){var a,b;return b=e,a=C(),null===a&&(a=B()),null!==a&&(a=function(a,b){return{type:"NumericLiteral",value:b}}(b,a)),null===a&&(e=b),a}function B(){var a,c,d;if(d=e,/^[0-9]/.test(b.charAt(e))?(c=b.charAt(e),e++):(c=null,0===f&&k("[0-9]")),null!==c)for(a=[];null!==c;)a.push(c),/^[0-9]/.test(b.charAt(e))?(c=b.charAt(e),e++):(c=null,0===f&&k("[0-9]"));else a=null;return null!==a&&(a=function(a,b){return parseInt(b.join(""))}(d,a)),null===a&&(e=d),a}function C(){var a,c,d,g,h;return g=e,h=e,a=B(),null!==a?(46===b.charCodeAt(e)?(c=".",e++):(c=null,0===f&&k('"."')),null!==c?(d=B(),null!==d?a=[a,c,d]:(a=null,e=h)):(a=null,e=h)):(a=null,e=h),null!==a&&(a=function(a,b){return parseFloat(b.join(""))}(g,a)),null===a&&(e=g),a}function D(){var a,c,d,g;if(g=e,/^[\-+]/.test(b.charAt(e))?(a=b.charAt(e),e++):(a=null,0===f&&k("[\\-+]")),a=null!==a?a:"",null!==a){if(/^[0-9]/.test(b.charAt(e))?(d=b.charAt(e),e++):(d=null,0===f&&k("[0-9]")),null!==d)for(c=[];null!==d;)c.push(d),/^[0-9]/.test(b.charAt(e))?(d=b.charAt(e),e++):(d=null,0===f&&k("[0-9]"));else c=null;null!==c?a=[a,c]:(a=null,e=g)}else a=null,e=g;return a}function E(){var a,b;return f++,b=e,a=F(),null!==a&&(a=function(a,b){return b}(b,a)),null===a&&(e=b),f--,0===f&&null===a&&k("identifier"),a}function F(){var a,b,c,d,g;if(f++,d=e,g=e,a=o(),null!==a){for(b=[],c=o();null!==c;)b.push(c),c=o();null!==b?a=[a,b]:(a=null,e=g)}else a=null,e=g;return null!==a&&(a=function(a,b,c){return b+c.join("")}(d,a[0],a[1])),null===a&&(e=d),f--,0===f&&null===a&&k("identifier"),a}function G(){var a,c,d,g,h,i,j;return i=e,a=E(),null!==a&&(a=function(a,b){return{type:"Variable",name:b}}(i,a)),null===a&&(e=i),null===a&&(a=A(),null===a&&(i=e,j=e,40===b.charCodeAt(e)?(a="(",e++):(a=null,0===f&&k('"("')),null!==a?(c=z(),null!==c?(d=P(),null!==d?(g=z(),null!==g?(41===b.charCodeAt(e)?(h=")",e++):(h=null,0===f&&k('")"')),null!==h?a=[a,c,d,g,h]:(a=null,e=j)):(a=null,e=j)):(a=null,e=j)):(a=null,e=j)):(a=null,e=j),null!==a&&(a=function(a,b){return b}(i,a[2])),null===a&&(e=i))),a}function H(){var a,b,c,d,f;return a=G(),null===a&&(d=e,f=e,a=I(),null!==a?(b=z(),null!==b?(c=H(),null!==c?a=[a,b,c]:(a=null,e=f)):(a=null,e=f)):(a=null,e=f),null!==a&&(a=function(a,b,c){return{type:"UnaryExpression",operator:b,expression:c}}(d,a[0],a[2])),null===a&&(e=d)),a}function I(){var a;return 43===b.charCodeAt(e)?(a="+",e++):(a=null,0===f&&k('"+"')),null===a&&(45===b.charCodeAt(e)?(a="-",e++):(a=null,0===f&&k('"-"')),null===a&&(33===b.charCodeAt(e)?(a="!",e++):(a=null,0===f&&k('"!"')))),a}function J(){var a,b,c,d,f,g,h,i,j;if(h=e,i=e,a=H(),null!==a){for(b=[],j=e,c=z(),null!==c?(d=K(),null!==d?(f=z(),null!==f?(g=H(),null!==g?c=[c,d,f,g]:(c=null,e=j)):(c=null,e=j)):(c=null,e=j)):(c=null,e=j);null!==c;)b.push(c),j=e,c=z(),null!==c?(d=K(),null!==d?(f=z(),null!==f?(g=H(),null!==g?c=[c,d,f,g]:(c=null,e=j)):(c=null,e=j)):(c=null,e=j)):(c=null,e=j);null!==b?a=[a,b]:(a=null,e=i)}else a=null,e=i;return null!==a&&(a=function(a,b,c){for(var d=b,e=0;c.length>e;e++)d={type:"MultiplicativeExpression",operator:c[e][1],left:d,right:c[e][3]};return d}(h,a[0],a[1])),null===a&&(e=h),a}function K(){var a;return 42===b.charCodeAt(e)?(a="*",e++):(a=null,0===f&&k('"*"')),null===a&&(47===b.charCodeAt(e)?(a="/",e++):(a=null,0===f&&k('"/"'))),a}function L(){var a,b,c,d,f,g,h,i,j;if(h=e,i=e,a=J(),null!==a){for(b=[],j=e,c=z(),null!==c?(d=M(),null!==d?(f=z(),null!==f?(g=J(),null!==g?c=[c,d,f,g]:(c=null,e=j)):(c=null,e=j)):(c=null,e=j)):(c=null,e=j);null!==c;)b.push(c),j=e,c=z(),null!==c?(d=M(),null!==d?(f=z(),null!==f?(g=J(),null!==g?c=[c,d,f,g]:(c=null,e=j)):(c=null,e=j)):(c=null,e=j)):(c=null,e=j);null!==b?a=[a,b]:(a=null,e=i)}else a=null,e=i;return null!==a&&(a=function(a,b,c){for(var d=b,e=0;c.length>e;e++)d={type:"AdditiveExpression",operator:c[e][1],left:d,right:c[e][3]};return d}(h,a[0],a[1])),null===a&&(e=h),a}function M(){var a;return 43===b.charCodeAt(e)?(a="+",e++):(a=null,0===f&&k('"+"')),null===a&&(45===b.charCodeAt(e)?(a="-",e++):(a=null,0===f&&k('"-"'))),a}function N(){var a,b,c,d,f,g,h,i,j;if(h=e,i=e,a=L(),null!==a){for(b=[],j=e,c=z(),null!==c?(d=O(),null!==d?(f=z(),null!==f?(g=L(),null!==g?c=[c,d,f,g]:(c=null,e=j)):(c=null,e=j)):(c=null,e=j)):(c=null,e=j);null!==c;)b.push(c),j=e,c=z(),null!==c?(d=O(),null!==d?(f=z(),null!==f?(g=L(),null!==g?c=[c,d,f,g]:(c=null,e=j)):(c=null,e=j)):(c=null,e=j)):(c=null,e=j);null!==b?a=[a,b]:(a=null,e=i)}else a=null,e=i;return null!==a&&(a=function(a,b,c){for(var d=b,e=0;c.length>e;e++)d={type:"Inequality",operator:c[e][1],left:d,right:c[e][3]};return d}(h,a[0],a[1])),null===a&&(e=h),a}function O(){var a;return"<="===b.substr(e,2)?(a="<=",e+=2):(a=null,0===f&&k('"<="')),null===a&&(">="===b.substr(e,2)?(a=">=",e+=2):(a=null,0===f&&k('">="')),null===a&&(60===b.charCodeAt(e)?(a="<",e++):(a=null,0===f&&k('"<"')),null===a&&(62===b.charCodeAt(e)?(a=">",e++):(a=null,0===f&&k('">"'))))),a}function P(){var a,c,d,g,h,i,j,l,m;if(j=e,l=e,a=N(),null!==a){for(c=[],m=e,d=z(),null!==d?("=="===b.substr(e,2)?(g="==",e+=2):(g=null,0===f&&k('"=="')),null!==g?(h=z(),null!==h?(i=N(),null!==i?d=[d,g,h,i]:(d=null,e=m)):(d=null,e=m)):(d=null,e=m)):(d=null,e=m);null!==d;)c.push(d),m=e,d=z(),null!==d?("=="===b.substr(e,2)?(g="==",e+=2):(g=null,0===f&&k('"=="')),null!==g?(h=z(),null!==h?(i=N(),null!==i?d=[d,g,h,i]:(d=null,e=m)):(d=null,e=m)):(d=null,e=m)):(d=null,e=m);null!==c?a=[a,c]:(a=null,e=l)}else a=null,e=l;return null!==a&&(a=function(a,b,c){for(var d=b,e=0;c.length>e;e++)d={type:"Equality",operator:c[e][1],left:d,right:c[e][3]};return d}(j,a[0],a[1])),null===a&&(e=j),a}function Q(a){a.sort();for(var b=null,c=[],d=0;a.length>d;d++)a[d]!==b&&(c.push(a[d]),b=a[d]);return c}function R(){for(var a=1,c=1,d=!1,f=0;Math.max(e,g)>f;f++){var h=b.charAt(f);"\n"===h?(d||a++,c=1,d=!1):"\r"===h||"\u2028"===h||"\u2029"===h?(a++,c=1,d=!0):(c++,d=!1)}return{line:a,column:c}}var d={start:l,Statement:m,SourceCharacter:n,IdentifierStart:o,WhiteSpace:p,LineTerminator:q,LineTerminatorSequence:r,EOS:s,EOF:t,Comment:u,MultiLineComment:v,MultiLineCommentNoLineTerminator:w,SingleLineComment:x,_:y,__:z,Literal:A,Integer:B,Real:C,SignedInteger:D,Identifier:E,IdentifierName:F,PrimaryExpression:G,UnaryExpression:H,UnaryOperator:I,MultiplicativeExpression:J,MultiplicativeOperator:K,AdditiveExpression:L,AdditiveOperator:M,InequalityExpression:N,InequalityOperator:O,LinearExpression:P};if(void 0!==c){if(void 0===d[c])throw Error("Invalid rule name: "+a(c)+".")}else c="start";var e=0,f=0,g=0,h=[],S=d[c]();if(null===S||e!==b.length){var T=Math.max(e,g),U=b.length>T?b.charAt(T):null,V=R();throw new this.SyntaxError(Q(h),U,T,V.line,V.column)}return S},toSource:function(){return this._source}};return b.SyntaxError=function(b,c,d,e,f){function g(b,c){var d,e;switch(b.length){case 0:d="end of input";break;case 1:d=b[0];break;default:d=b.slice(0,b.length-1).join(", ")+" or "+b[b.length-1]}return e=c?a(c):"end of input","Expected "+d+" but "+e+" found."}this.name="SyntaxError",this.expected=b,this.found=c,this.message=g(b,c),this.offset=d,this.line=e,this.column=f},b.SyntaxError.prototype=Error.prototype,b}();
    }).call(
      (typeof module != "undefined") ?
          (module.compiled = true && module) : this
    );
    
    },{}]},{},[1])(1)
    });